Corso java base

Post on 02-Jul-2015

728 views 3 download

description

Corso Java Base

Transcript of Corso java base

STORIA

• Java nasce nel 1991, da una idea di James Gosling

• Il progetto doveva essere finalizzato ad una piattaforma software, indipendente dall' hardware, a basso costo per prodotti elettronici (elettronica embedded)

• Inizialmente il nome del linguaggio era Oak

• Nel 1994, per problemi di copyright, il nome divenne Java

• Le prime versioni erano disponibili solo per Sparc

• Nel 1995 vennero rilasciate le prime versioni per Windows (NT,95)

• Nel gennaio del 1996 venne rilasciata la versione 1.0

Cosa è JAVA ?

• Una piattaforma • Un linguaggio di programmazione

PIATTAFORMA

• Una piattaforma è un ambiente hardware o software in cui le applicazioni vivono • Tipicamente una piattaforma è costituita da un sistema operativo e dal sottostante hardware

PIATTAFORMA JAVA

• Java è una piattaforma esclusivamente software e si deve appoggiare su altre piattaforme basate su hardware

• E’ composta da:• Java Virtutal Machine (JVM)• Application Programming Interface (API)• Tools: compilatore, debugger, …

JAVA VIRTUAL MACHINE

• Una macchina virtuale è una macchina astratta ideata per essere implementata su architetture esistenti, nasconde il sistema operativo sottostante

• Il compilatore compila il linguaggio non in istruzioni macchina ma in bytecode, che viene interpretato dalla virtual machine

JAVA VIRTUAL MACHINE

• La virtual machine garantisce la portabilità delle applicazioni• E’ necessario che esista una virtual machine per ogni sistema su cui voglio eseguire la mia applicazione• Write Once Run Anywhere

LINGUAGGIO JAVA

Java è un linguaggio ad oggetti di alto livello, semplice, sicuro ed affidabile, portabile, distribuito, multithreaded e dinamico

Semplice• semplice da apprendere• deriva dal c++, ma cerca di eliminarne gli aspetti negativi:

overloading degli operatoriereditarietà multiplaconversione automatica del tipopuntatori

• garbage collector automaticosemplifica la scrittura dei programmielimina molte probabilità di errorememoria allocata al momento della creazione degli oggettimemoria liberata automaticamente

LINGUAGGIO JAVA

Object Oriented• deriva dal C++• puramente ad oggetti, esistono solo classi e metodi• permette di riusare componenti software

Sicuro e affidabile• elimina i puntatori• non si può accedere agli oggetti indirettamente• fortemente tipizzato, la conversione di tipo è esplicita• controllo degli errori da parte del compilatore e del sistema di runtime• restrizioni per la sicurezza

LINGUAGGIO JAVA

Portabile • è interpretato, viene creato un bytecode• i formati dei dati sono indipendenti dalla macchina• compilatori jit per aumentare le prestazioni

Multithreaded• strumenti per la gestione sicura dei thread• sincronizzazione

Dinamico• il sistema di runtime si occupa del collegamento dinamico tra le classi• è un componente chiave per le applicazioni distribuite

VERSIONI

• JSE – Java Standard Edition

Fornisce un ambiente per applicazioni desktop e server

• JEE – Java Enterprise EditionE’ basato sulla piattaforma SE e fornisce servizi per applicazioni entrerpise, web application, SOA

• JME – Java Micro EditionFornisce un ambiente per applicazioni che devono essere eseguite su dispositivi mobili o embedded

VERSIONI

SE EE ME

JDK 1.0 - 1996JDK 1.1 - 1997J2SE 1.2 - 1999J2SE 1.3 - 2000J2SE 1.4 - 2002J2SE 5.0 - 2004Java SE 6 - 2006

Versione corrente

Java SE 6 Update 19

Java SE 7 Milestone 5

J2EE 1.2 - 1999

J2EE 1.3 - 2001

J2EE 1.4 - 2003

Java EE 5 - 2006

Versione corrente

Java EE 6

J2ME WTK

• CLDC

• CDC

Versione corrente

J2ME WTK 2.5.2CLDC 1.1

MIDP 2.0

Java ME SDK 3.0 EA

JDK + IDE

• Esistono due versioni: JDK e JRE• JDK contiene la jvm e tutti gli strumenti per lo sviluppo: compilatore, debugger, ecc.• JRE contiene solo il runtime per eseguire le applicazioni java

•Scaricare e installare il jdk:http://java.sun.com/javase/downloads/index.jsp

• Settare il path e la variabile di ambiente JAVA_HOME

• IDE open per Java:• Eclipse• NetBeans

COMMENTI

Java mette a disposizione tre modi per indicare i commenti :

// Commento su una singola linea

/* Commento su più linee, si può andare a capo,deve essere terminato con i caratteri */

/** Commento interpretato dalla utility Javadoc, in questo modo è possibile generare automaticamente una documentazione in html */

I commenti non possono essere nidificati.

VARIABILI

Una variabile è un nome simbolico per una porzione di memoria.

Prima di essere utilizzata, deve sempre essere dichiarata.

Ogni variabile è caratterizzata da un tipo e da un nome.

Java è un linguaggio fortemente tipizzato.

NOMI DI VARIABILI

Il nome della variabile deve cominciare con una lettera dell’alfabeto o con uno dei seguenti caratteri: _ $

Per lettere si intendono i caratteri ‘a’-‘z’, ‘A’-‘Z’ e qualsiasi altro carattere Unicode che indichi una lettera in un lingua qualsiasi.

I caratteri successivi al primo possono contenere anche cifre ‘0’-‘9’

Tutti gli altri caratteri non possono essere utilizzati (%,&,# ecc.).

Non possono essere utilizzate parole riservate.

Java è case sensitive : la variabile Var1 è diversa da var1 .

Non ci sono limiti di lunghezza.

ESEMPI DI NOMI DI VARIABILI

NOMI CORRETTI

a abracadabra AbraCadabraabra_cadabra abra$ $abraabra1 è_abra_cadabra _abra

NOMI ERRATI

abra# abra-cadabra abstract2abra abra*cadabra ?abra!abra cadabra abra&cadabra abra.cadabra

CONVENZIONE SUI NOMI DI VARIABILI

• La prima lettera va minuscola

• Se il nome è composto da più parole, la prima lettera di ogni parola va maiuscola es:

variabileMoltoLunga

• Se il nome comprende un acronimo questo deve essere maiuscolo, a meno che non sia la prima parola del nome es:

variabileChePuntaUnXML xmlNellaVariabile

• Non prefissare le variabili con un identificatore del tipo

PAROLE RISERVATE

abstract boolean break byte case

catch char class default false

final for if implements import

instanceof int interface long native

new null package protected private

public return short static super

switch synchronized this throw throws

transient true try void while

TIPI DI VARIABILI

Una variabile può essere definita come uno dei seguenti tipi :

• Tipi primitiviNumerici : interi o a virgola mobileCaratteriBooleani

• Classi

• Array

TIPI PRIMITIVI

Numerici interibyte 1 byte da -128 a 127

short 2 byte da -32.768 a 32.767 int 4 byte da -2.147.483.648 a 2.147.483.647

long 8 byte da –263 a 263 –1

Numerici a virgola mobilefloat 4 byte ± 3.4028234E+38

(7 cifre decimali significative)

double 8 byte ±1.79769313486231570E+308(15 cifre decimali significative)

Caratterichar 2 byte 65536 caratteri Unicode,39000 utilizzati

Booleaniboolean true,false

DICHIARAZIONI DI VARIABILI

Le variabili devono sempre essere dichiarate ed inizializzate prima di essere usate.

int abra;float cadabra;

Più variabili dello stesso tipo possono essere dichiarate insieme :char inizialeNome, inizialeCognome;

Inizializzazione :abra=5;

Una variabile può essere dichiarata e inizializzata nello stesso istante

int cont1=0;int cont2,cont3=1;

ASEEGNAMENTO DI LETTERALI

Interi sono considerati int per default0 1 25 -1254102 07 -01230x0 0x2a 0x1FF

Virgola mobile sono considerati double per default1.0 -47.1 1.22e193.16E-9 6.2f 2.14e-2f

Boolean true false

Caratteri ’a’ ’\n’ ’u\00f6’

CODICI DI CARATTERE

\n nuova riga

\t tabulazione

\b cancella il carattere a sinistra

\r ritorno a capo

\f avanzamento pagina

\\ backslash

\’ apice

\” doppio apice

CONVERSIONI

Ogni tipo di dato numerico può essere convertito in un altro tipo numerico.Java converte automaticamente un tipo in uno più esteso :

byte var1=5;int var2;var2=var1;

Tutte le operazioni tra short e byte danno come risultato un int

byte a,b=2;a=b+1; // Errore

Se due operatori sono diversi, Java converte automaticamente quello meno esteso in quello più esteso

float a,b=12.4f;int d,c=2;a=b-c;d=b-c; //Errore

CONVERSIONI

Le conversioni inverse vanno dichiarate esplicitamente con una azione denominata cast che ha il seguente formato:

(tipo_di_destinazione) espressione

double a=12.43;float b;b=(float) a;

C’è possibilità di perdita di dati, anche nelle conversioni automatiche c’è possibilità di perdita di dati.

int a=1234567891;float b;b=a; //

b=1.2345679e9=1234567900

I valori booleani non possono essere convertiti in numero e viceversa.

OPERATORE DI ASSEGNAMENTO

Il simbolo = assegna l’espressione di destra alla variabile a sinistra :

int var1=10;

Un’ espressione è una istruzione che restituisce un valore.

Le espressioni vengono sempre valutate prima di essere assegnate alle variabili.

Le espressioni possono quindi contenere degli operatori:

int var1=10+2;

L’assegnamento può essere multiplo:

var1=var2=var3=0;

OPERATORI DI BASE

+,-,*,/,%

/ restituisce un numero intero se i due operandi sono interirestituisce un numero in virgola mobile se uno dei due

operandi è in virgola mobile.

% è l’operatore di modulo, restituisce il resto della divisione tra due interi:Es: 10% 3 = 1

- è usato anche per negare un operatore singolo.

Non esiste l’elevamento a potenza, bisogna utilizzare una “funzione”.

ASSEGNAMENTI PARTICOLARI

Sono assegnamenti combinati con operatori, la cui sintassi deriva dal C.

Invece di utilizzare la seguente forma:

a = a op b; op è un operatore

Posso scrivere :

a op = b;Es:

a + = 2; // a=a+2;a * = -1; // a=a*(-1)

OPERATORI DI INCREMENTO E DECREMENTO

Posso utilizzare una delle seguenti tre forme:

var=var+1;var+=1;var++;

++ e -- sono operatori di incremento unitario possono essere utilizzati come prefisso o come suffisso di una variabile.

var++; ++var;var2=var1++; // assegna e poi incrementavar2=++var1; // incrementa e poi assegna

Esint var1=7,var2=7;int res1=2*++var1;int res2=2*var2++;

OPERATORI RELAZIONALI

Servono per confrontare i valori di più variabili o espressioni.Tutti i confronti restituiscono un valore booleano.

= = uguale< minore> maggiore<= minore o uguale>= maggiore o uguale!= diverso

Le espressioni che producono valori booleani, possono essere combinate tra di loro mediante operatori logici.

OPERATORI LOGICI

Gli operatori logici possono agire solo su operandi, o espressioni, di tipo booleano.

& && and| || or^ xor! not

& e | valutano entrambe i membri dell’operatore&& e || sono operatori condizionali, cioè valutano l’operando a destra solo in alcuni casi, dipendenti dall’operatore di sinistra.Es:(1>2) & (2>3) valuta entrambe le condizioni(1>2) && (2>3) valuta solo la prima condizione, essendo

falsa, il risultato non può che essere falso (2>1)||(3<1) valuta solo la prima condizione, essendo

vera, il risultato non può che essere vero

OPERATORI SUI BIT

& and bit a bit| or bit a bit^ xor bit a bit<< scorrimento a sinistra>> scorrimento a destra>>> scorrimento a destra con riempimento di zeri~ complemento bit a bit<<= scorrimento a sinsitra con assegnamento (x=x<<y)>>= scorrimento a destra con assegnamento (x=x>>y)>>>= scorrimento a destra con riempimento di zeri e

assegnamento&= and con assegnamento|= or con assegnamento^= xor con assegnamento

PRECEDENZE TRA GLI OPERATORI

. [] ()++ -- ~ ! * / %+ -<< >> >>>< > <= >=== !=&^|&&||= += -= *= /=Gli operatori con la stessa precedenza sono eseguiti da sinistra a destra.

FLUSSI DI CONTROLLO

I programmi seguono un flusso sequenziale, eseguono cioè le operazioni in successione, una dopo l’altra.

E’ possibile alterare il flusso sequenziale tramite istruzioni in uno dei seguenti flussi:

• Selezionesolo una parte di codice tra tante possibili è eseguita

• Ciclouna parte di codice è eseguita ripetute volte

• Trasferimentosi passa da una punto del codice ad un punto diverso

BLOCCHI DI ISTRUZIONI

Un blocco è un insieme di istruzioni racchiuse tra parentesi graffe {}

I blocchi possono essere allo stesso livello o innestati.

I blocchi definiscono l’ambito di validità (scope) delle variabili, una variabile definita in un blocco non è visibile all’esterno ma lo è nei blocchi contenuti, quando si esce dal blocco la variabile viene eliminata.

Non è possibile dichiarare due variabili con lo stesso nome all’interno dello stesso blocco o in due blocchi diversi ma innestati tra di loro.

IF

L’istruzione if permette di eseguire porzioni diverse di codice in base al risultato di una condizione.

if (condizione)istruzione1;

elseistruzione2;

Se la condizione è verificata (true), allora viene eseguita l’istruzione1, altrimenti viene eseguita l’istruzione2.

La condizione deve sempre essere racchiusa tra parentesi.

La clausola else non è obbligatoria, se viene omessa e la condizione è falsa, non viene eseguito nulla e il programma continua nel suo flusso sequenziale.

IF

Le singole istruzioni possono essere sostituite da blocchi di istruzioni

if (condizione){istruzione1;istruzione2;

}else{

istruzione3;istruzione4;

}

E’ buona norma inserire le parentesi graffe anche nei casi di singola istruzione.

IF NIDIFICATI

Posso inserire un istruzione if all’interno di un’altra istruzione if.L’ else è sempre riferito all’ if più vicino.

if (velocità>30){if (velocità)>50{

multa;else

velocita_ok;else

troppo_lento;Si può utilizzare anche la forma else if.

if (velocità>50)multa;

else if (velocità<30)troppo_lento;

else velocità_ok;

OPERATORE CONDIZIONALE

L’operatore condizionale è un’espressione e quindi a differenza dell’istruzione if produce un valore.

condizione ? seVero : seFalso

Condizione è un’espressione che restituisce un valore true o false.Se la condizione è true viene restituito il valore seVero, altrimenti viene restituito il valore seFalso.

int minore = x<y ? x : y;

int minore;if (x<y)

minore=x;else

minore=y;

SWITCH

L’istruzione switch permette di scegliere una tra più alternative.La variabile utilizzata per il confronto può essere char, byte, short, int, non si possono utilizzare float,double e oggetti ( e quindi stringhe) tranne le classi wrapper dei tipi primitivi (Integer, …)switch(variabile){

case const_1 :istruzione1;break;

case const_2 :istruzione2;break;

default :istruzione3;

}const_1 e const_2 devono essere dei letterali, non possono essere delle variabili.L’istruzione break serve per uscire dallo switch.

FOR

Il ciclo for permette di ripetere un’istruzione o un blocco di istruzioni, un numero prefissato di volte.La forma generale di un ciclo Java è la seguente:

for (inizializzazione;condizione;incremento){istruzioni;

}

inizializzazione : è un’espressione eseguita all’avvio del ciclocondizione: è la condizione valutata ad ogni ripetizioneincremento: è un espressione eseguita alla fine di ogni ciclo

Questi parametri non sono obbligatori, possono anche essere omessi.

L’inizializzazione e l’incremento possono comprendere più espressioni separate da virgole.

FOR - Esempi

for (int i = 0; i < 10; i++) {System.out.println(i);

}

for (int i = 0; i < 10; ) {System.out.println(i++);

}

int i = 0;for (; i < 10; ) {

System.out.println(i++);}

FOR EACH

Questo costrutto è stato inserito nel jdk 5Permette di iterare su array o collezioni, o su oggetti che implementano l’interfaccia Iterable.

for(type var : arr){<corpo>

}

for(type var : coll){ <corpo>

}

for(int i=0;i<arr.length;i++){type var=arr[i];

<corpo>}

for(Iterator iter = coll.iterator(); iter.hasNext(); ){

type var = iter.next(); <corpo>

}

FOR EACH - Quando

• Solo accesso. Gli elementi non possono essere assegnati

• Solo su strutture singole. Non è possibile utilizzare due strutture simultaneamente, per esempio per confrontare due array.

• Elementi singoli. Non si possono utilizzare più elementi della stessa struttura, per esempio per confrontare elementi successivi.

• Solo in avanti. E’ possibile iterare solo in avanti e con passi singoli.

• Non è possibile utilizzarla se si deve essere compatibili con versioni Java precedenti la 5.

WHILE

Il ciclo while esegue ripetutamente un’istruzione o un blocco per tutto il tempo in cui una data condizione è vera.

while (condizione){// corpo del ciclo

}

La condizione viene sempre valutata all’inizio del ciclo, se è vera viene eseguito il blocco, altrimenti non viene eseguito.

DO ... WHILE

Il ciclo do è molto simile al ciclo while, con l’unica differenza che la condizione viene valutata alla fine del ciclo, quindi il blocco di istruzioni verrà sempre eseguito almeno una volta.

do{ // corpo del ciclo

} while (condizione);

BREAK - CONTINUE

L’istruzione break permette di uscire da una istruzione switch o da un ciclo (for, while o do).Trasferisce il controllo alla prima istruzione successiva al ciclo o allo switch.

while (velocità<50) {velocità++;if (--benzina==0)

break;}

// multa o benzinaio

L’istruzione continue interrompe il ciclo in corso e lo riprende dall’inizio.Per il ciclo for, prima esegue l’incremento e poi riprende il blocco dall’inizio.

ETICHETTE

Sia break che continue possono recare un’etichetta, l’etichetta indica un ciclo e specifica da quale ciclo devono uscire in presenza di cicli nidificati.

break etichetta;continue etichetta;

L’ etichetta va posta all’inizio del ciclo con la seguente forma:

etichetta:

MAIN

Struttura di una applicazione java standalone.E’ necessario definire una classe principale che implementerà il metodo main.

public class MainClass {

/** * @param args */

public static void main(String[] args) {// TODO Auto-generated method stub

}}

OBJECT ORIENTED TECNOLOGY

E’ un insieme di metodologie di analisi, progettazione e programmazione che prendono spunto dagli oggetti del mondo reale, acquisendone i concetti di caratteristica e comportamento.

Pregi• Analisi e progettazione più semplici e chiare• Sviluppo e manutenzione più veloci• Riusabilità del codice• Supporto per architetture distribuite

Difetti• Curva di apprendimento lenta

ASTRAZIONE

Procedimento tendente a sostituire con una formula o con simboli la concreta molteplicità del reale (Devoto-Oli)

I linguaggi di programmazione sono astrazioni della macchina su cui operano.

I problemi da risolvere sono astrazioni della realtà.

Abbiamo quindi uno spazio dei problemi e uno spazio delle soluzioni e dobbiamo trovare una relazione tra i due.

OT permette di avere una relazione di tipo lineare.

PROGRAMMAZIONE ORIENTATA AGLI OGGETTI

E’ una tecnica (modello di programmazione) che punta i riflettori sui dati (oggetti) e quindi su come agire su di essi.

La programmazione tradizionale parte invece dagli strumenti e successivamente si preoccupa dei dati.

Si basa sullo sviluppo di componenti software completi, denominati oggetti.

Questi oggetti sono modellati sulla base delle cose che si vedono nel mondo reale.

Gli oggetti sono definiti in termini di informazione che contengono e di operazioni che forniscono per l'uso e la manipolazione di tali informazioni.

OGGETTI

Una lampada è un oggetto, che contiene informazioni relative al suo stato (accesa o spenta) e metodi per accedere allo stato della lampada (accendi o spegni).

L'informazione contenuta nell'oggetto, indipendentemente dal suo stato, rappresenta i dati dell'oggetto.

Alcuni metodi dell'oggetto forniscono informazioni relative ai dati dell'oggetto (accesso in lettura), altri consentono di modificare i dati (accesso in scrittura) e altri ancora di creare gli oggetti (constructor).

METODOLOGIA ORIENTATA AGLI OGGETTI

Oggetti: sono le cose.Classi: definizione delle cose.

Individuare:- quali classi e oggetti esistono- la loro struttura, il loro comportamento e l'utilizzo- le relazioni che esistono tra le classi e tra gli oggetti

OGGETTO

per OT è un'astrazione di un oggetto realeper il software è una struttura dati con funzioni associate

Gli oggetti fanno qualcosa (una penna scrive).

Gli oggetti mantegono al loro interno informazioni sullo stato: queste informazioni sono dette attributi (quantità di inchiostro in una penna).

Gli oggetti sono unici (come una riga di un database).

Gli oggetti possono essere formati da altri oggetti.

CLASSI

Una classe è l'insieme delle specifiche di tutte le operazioni, di tutti gli attributi e di tutti i legami con altri oggetti per un determinato tipo di oggetto.

Si dice che un oggetto è un'istanza di una classe, con particolari valori degli attributi.

Le classi permettono di pensare a concetti -> livello superiore di astrazione che permette la classificazione.

La classe è una definizione, un oggetto, invece, esiste a runtime.

La classe è il progetto, mentre l’oggetto è la costruzione reale fatta seguendo il progetto

CARTTERISTICHE DELL’ OOP

INCAPSULAMENTO

EREDITARIETA’

POLIMORFISMO

INCAPSULAMENTO

Meccanismo che serve a nascondere come un oggetto è fatto, noi operiamo con l'oggetto tramite le operazioni (interfaccia).(Esempio bancomat, cambio il software o l'hardware ma il funzionamento non cambia).

L'incapsulamento è una caratteristica importante per lo sviluppo di software affidabile.

EREDITARIETA’

Le classi possono avere in comune delle caratteristiche -> ereditarietà è un rapporto tra le classi (valivolo ed aereo o elicottero).

E' un meccanismo che velocizza la produzione del software poiché nuove classi possono essere derivate a partire da classi esistenti: la sottoclasse deve avere il comportamento della superclasse.

CLASSIFICAZIONE

La classificazione è un metodo molto diffuso utilizzato per l'organizzazione della conoscenza.Se una data categoria di oggetti compare nell'albero di classificazione, essa soddisfa le propreità di tutte le categorie di oggetti che si trovano ad un livello superiore dell'albero. Il fatto che una categoria di livello inferiore condivida tutte le caratteristiche delle categorie che si trovano 'sopra' è noto come ereditarietà.Si dice che una classe A estende un'altra classe B se contiene tutti i dati contenuti nella classe B e implementa tutti i metodi implementati dalla classe B. La classe A è detta sottoclasse della classe B e la classe B è detta superclasse della classe A. Se una classe è sottoclasse di un'altra classe eredita tutti i dati e i metodi della superclasse.

EREDITARIETA’ MULTIPLA

Quando una classe estende diverse classi appartenenti a differenti diramazioni dell'albero si parla di ereditarietà multipla.

Il problema maggiore è dato dalla difficoltà di determinare quale superclasse utilizzare in determinate condizioni.

Java non supporta l'ereditarietà multipla, solo ereditarietà singola. I vantaggi dell'ereditarietà multipla sono ottenuti tramite le interfacce.

POLIMORFISMO

Il polimorfismo è la capacità degli oggetti di assumere “forme” e quindi comportamenti differenti all’interno di una gerarchia

Questo meccanismo viene realizzato mediante due meccanismi: overloading e overriding.

Per poter utilizzare questi meccanismi è necessario uno specifico supporto della virtual machine

COLLEGAMENTO DINAMICO

La capacità di rinviare fino al momento di runtime decisioni sulla classe alla quale appartiene un oggetto e sui metodi di accesso all'oggetto è nota come collegamento dinamico.

Il compilatore e l'interprete lavorano congiuntamente in modo da fornire un codice eseguibile con le capacità necessarie per interfacciarsi dinamicamente con oggetti sconosciuti durante l'esecuzione del programma.

JAVA

Java è un linguaggio di programmazione orientato agli oggetti puro.

In Java ci sono dei tipi di dato primitivi.

Per creare delle strutture dati è necessario utilizzare gli oggetti.

Gli oggetti si compongono di dati:attributi, variabili di istanza o stato

e di comportamenti (funzionalità):operazioni o metodi di istanza.

Gli oggetti sono istanze delle classi.

DEFINIZIONE DI UNA CLASSE

Parola riservata class

Nome della classe, per convenzione incomincia con una lettera maiuscola.

Dichiarazione delle proprietà della classe: tipo e nome (per convenzione incomincia con una lettera minuscola).

Esempio:

class ContoCorrente{int codice;int saldo;

}

DEFINIZIONI DI METODI

La definizione dei metodi può avvenire solo all’interno della definizione di una classe.

Un metodo si compone di un valore di ritorno (void, return), di un nome (per convenzione incomincia con una lettera minuscola) e di una lista di parametri.

Esempio:

class ContoCorrente{int codice;int saldo;void versare (int valore){

saldo += valore; }

}

CREAZIONE DI OGGETTI

Gli oggetti vengono creati utilizzando l’operatore new:

oggetto = new NomeClasse();

L’operatore new:• alloca memoria• chiama il metodo per l’inizializzazione (costruttore)• restituisce un riferimento al nuovo oggetto

Esempio:

ContoCorrente cc = new ContoCorrente();

RIFERIMENTI

Le variabili oggetto valgono null finché non vengono inizializzate.

Un oggetto può essere ‘dimenticato’ assegnando al riferimento il valore null.

Si possono avere più riferimenti ad uno stesso oggetto.

Esempio:

ContoCorrente cc, ca;……if (cc == null)

cc = new ContoCorrente();ca = cc;

PROPRIETA’ PRIMITIVE ED OGGETTI

Le proprietà primitive, all’atto della creazione di un oggetto, vengono inizializzate:• valori numerici a zero• booleani a false• valori char a ‘\0’

Le proprietà non primitive, cioè gli oggetti, vengono inizializzate a null.

ACCEDERE ALLE PROPRIETA’

Si accede alle proprietà di un oggetto attraverso il nome del riferimento e l’operatore ‘.’ (punto).

Esempio:

ContoCorrente cc = new ContoCorrente();cc.codice = 1023;….if (cc.saldo < 0)

cc.saldo = 0;

ACCEDERE AI METODI

Si accede ai metodi di un oggetto attraverso il nome del riferimento e l’operatore ‘.’ (punto).

Esempio

ContoCorrente cc = new ContoCorrente();cc.codice = 1023;….if (cc.saldo < 0)

cc.versare (10000);

PASSAGGIO DEI PARAMETRI

Solitamente su questo argomento si dice:

Le variabili di tipo primitivo sono passate per valore (copia).

La variabili di tipo oggetto sono passate per riferimento (side effects).

In realtà non è così, tutto è passato per valore, nel caso degli oggetti viene passato per valore il riferimento all’oggetto.Quindi viene copiato il “puntatore” all’oggetto, ma l’oggetto riferito è sempre lo stesso.

VARIABLE ARGUMENTS (VARARGS)

Introdotti dal jdk 5.

Nel caso in cui il numero dei parametri non sia conosciuto a priori, posso passare una collezione di parametri o un array, oppure dichiarare un numero variabile di argomenti.

public void metodo(<tipo>... nome){

All’interno del metodo, i valori sono raggruppati in un array.public int sum(int... intList){

int ret=0;for(int val:intList) {

ret +=val;}return(ret);

}

Ci può essere solo una serie di parametri variabili, e deve essere come ultimo parametro nel metodo

PACKAGE

I programmi Java sono organizzati in pacchetti (unità di compilazione). I pacchetti contengono il codice sorgente delle dichiarazioni di classe e di interfaccia. I pacchetti sono identificati dall'istruzione package, la prima in un file sorgente.

package nomePacchetto;

Se l'istruzione viene omessa, le classi e le interfacce dichiarate all'interno del pacchetto vengono inserite nel pacchetto predefinito, quello senza nome che è unico all'interno di una directory.

Il nome del pacchetto e la variabile di ambiente CLASSPATH vengono usate per trovare una classe.

L’ISTRUZIONE IMPORT

L'istruzione import è utilizzata per fare riferimento a classi e interfacce che sono dichiarate in altri pacchetti. Esistono tre forme di import:

import nomePacchetto.NomeClasse;import nomePacchetto.*;

La prima consente di far riferimento alle classi e interfacce identificate senza specificare il nome del relativo pacchetto.La seconda consente di far riferimento a tutte le classi e le interfacce contenute nel pacchetto senza specificare il nome del relativo pacchetto. In alternativa è possibile qualificare completamente l’oggetto da utilizzare:

nomePacchetto.NomeClasse.metodo()

STATIC IMPORT

Dalla versione 5 è stata inserita l’opzione import static che permette di referenziare variabili statiche (tipicamente costanti) senza doverle qualificare con il nome della classe.Es:

import static java.awt.Color;

è quindi possibile scrivere:

Color background = RED;

invece di

Color background = Color.RED;

E’ comunque sconsigliabile utilizzarlo.

INCAPSULAMENTO

La dichiarazione di una proprietà o di un metodo può essere preceduta da un modificatore di accesso:privatePublic

Esempioclass ContoCorrente{

private int saldo;public void setSaldo (int valore){

saldo = valore; }public int getSaldo (){

return saldo; }

}

IL RIFERIMENTO ‘THIS’

Il riferimento this può essere utilizzato per risolvere ambiguità sui nomi delle variabili o per operazioni di callback.Esempio

class ContoCorrente{private int saldo;public void setSaldo (int saldo){

this.saldo = saldo; }public int getSaldo (){

return saldo; }public void stampa() {

Stampa st = new Stampa();st.eseguiStampa (this);

}}

OVERLOADING DEI METODI

All’interno di una classe è possibile definire metodi con lo stesso nome, lo stesso valore di ritorno ma una diversa lista di argomenti. Il compilatore analizzando i parametri della chiamata sceglie quale metodo deve essere invocato.

class ContoCorrente{private int saldo;public void setSaldo (int saldo){

this.saldo = saldo; }public void setSaldo (){

this.saldo = 12000; }public int getSaldo (){

return saldo;}

}

COSTRUTTORI

Metodi speciali per fornire una inizializzazione ad hoc delle proprietà.

Sono chiamati quando si crea un oggetto con l’istruzione new.

Hanno lo stesso nome della classe, possono avere una lista di parametri, ma non devono specificare un valore di ritorno.

Il compilatore fornisce un costruttore di default senza argomenti.

COSTRUTTORI

Se definisco un altro costruttore, il costruttore di default (implicito) viene ‘perso’ ed eventualmente devo definirlo esplicitamente.

Un costruttore può richiamare un altro costruttore, ma può essere solo la prima istruzione eseguita.

Si possono richiamare altri costruttori della stessa classe o costruttori della superclasse.

Se non specifico altrimenti, il costruttore della sottoclasse richiama il costruttore di default della superclasse.

USO DI THIS TRA COSTRUTTORI

Esempio

public ContoCorrente (int saldo, boolean attivo){this.saldo = saldo; this.attivo = attivo;

}// Non correttapublic ContoCorrente (int saldo){

this.saldo = saldo;this.attivo = true;

}

// Correttapublic ContoCorrente (int saldo){

this(saldo, true); }

PROPRIETA’ DI CLASSE

Appartengono ad una classe e sono quindi comuni a tutte le istanze di una classe.

Sono dichiarate con la parola riservata static.

Hanno valori di default nell’inizializzazione come le propietà delle istanze.

Inizializzazioni complesse tramite un blocco static.

Si accede ad esse tramite il nome della classe:

ContoCorrente.tassoInteresse = 0.05;

METODI DI CLASSE

Appartengono ad una classe e sono quindi utilizzati da tutte le istanze di una classe.

Sono dichiarati con la parola riservata static.

Servono per accedere alle proprietà statiche (di classe).

Si utilizzano per creare librerie di funzioni.

Si accede ad esse tramite il nome della classe.

ContoCorrente.setTassoInteresse (0.05);double a = Math.sqrt(b);

PROPRIETA’ FINAL

Il modificatore final definisce una proprietà che non puà essere modificata, posso assegnarla un valore solo la prima volta.

Non può essere modificata.Deve essere inizializzata.

Viene quindi utilizzato per le costanti.

Esempio:

class ContoCorrente{

private int saldo;public static final int maxPrelievo = 3000000;public ContoCorrente (int saldo){

this.saldo = saldo; }

}

METODI E CLASSI final

Un metodo definito come final non può essere ridefinito.Una classe definita final non può essere estesa.

Esempi

public final class Color{……}

public final boolean controllaPassword (String p){…..}

EREDITARIETA’

L’ereditarietà è quel meccanismo della OOP che permette di definire una classe specificando soltanto quello che la differenzia da un’altra classe.

E’ una tecnica che incoraggia a riutilizzare il software.

La classe originale è detta superclasse.

La classe derivata è detta sottoclasse.

EREDITARIETA’ IN JAVA

Parola riservata extends

Nella definizione di una classe va indicato quale classe estende. Una sola classe poiché l’ereditarietà è singola.

Se non si dichiara la superclasse di una classe vuol dire che la superclasse è Object.

Esempio:

class Taxi extends Auto{String licenza;

}

CARATTERISTICHE DELLA SOTTOCLASSE

La sottoclasse eredita automaticamente tutte le caratteristiche (proprietà e metodi) della superclasse.

Auto a = new Auto;…Taxi t = new Taxi();

L’oggetto t avrà tutte le proprietà della classe Auto.

Le proprietà della classe Auto che sono private non sono accessibili direttamente dagli oggetti della classe Taxi.

MODIFICATORI

Modificatore public

Gli attributi e i metodi preceduti da questo modificatore sono accessibili da tutte le altre classi.

Modificatore protected

Gli attributi e i metodi preceduti da questo modificatore sono accessibili da tutte le classi del package, dalle stottoclassi del package e dalle sottoclassi esterne al package.

MODIFICATORI

Modificatore private

Gli attributi e i metodi preceduti da questo modificatore sono accessibili solamente dalla stessa classe.

Modificatore di default

Gli attributi e i metodi che non sono preceduti da alcun modificatore sono accessibili da tutte le classi del package e dalle stottoclassi del package .

MODIFICATORI

nonosìsìda una sottoclasse esterna al package

nosìsìsìda una sottoclasse dello stesso package

nononosì da una qualsiasi classe esterna al package

nosì sì sì da una qualsiasi classe dello stesso package

sì sì sì sì dalla stessa classe

private default protected public Visibilità

METODI DELLA SOTTOCLASSE

I metodi di una superclasse sono utilizzabili da tutte le sottoclassi.

Class Taxi extends Auto{private String licenza;public void setLicenza (String licenza){

this.licenza = licenza;}public String getLicenza(){

return licenza;}

}………………Taxi t = new Taxi();t.setLicenza (“QW 987 YTR”);t.setTarga(“AD 098 BV”);

OVERRIDING

Una sottoclasse eredita tutti i metodi di una superclasse.

Una sottoclasse può sovrascrivere (ridefinire) un metodo ereditato, definendo di nuovo il metodo con lo stesso nome, lo stesso valore di ritorno e la stessa lista dei parametri.

Il metodo sovrascritto nasconde il vecchio metodo presente nell’albero di ereditarietà.

L’overriding non può variare il modificatore in maniera meno restrittiva.

INVOCARE UN METODO DELLA SUPERCLASSE

Un metodo sovrascritto nasconde il vecchio metodo definito nella superclasse.

La parola riservata super permette di far riferimento al metodo definito nella superclasse.

Esempio

public void visualizza(){super.visualizza();System.out.println(“Targa: “ + targa);

}

USO DI SUPER TRA COSTRUTTORI

Un costruttore di una sottoclasse può invocare un particolare costruttore della superclasse.

La chiamata al costruttore della superclasse deve essere al primo posto nel codice del costruttore della sottoclasse.

Esempio di costruttore

public Taxi (String targa, String licenza){super (targa);this.licenza = licenza;

}

ASSEGNAMENTI TRA CLASSE E SOTTOCLASSE

Ad un riferimento della superclasse si può assegnare un riferimento di una sottoclasse, poiché la sottoclasse è “del tipo della” superclasse.

Esempio

Auto a = new Taxi (“AD 098 YT”, “NUM 4563”);

Non si può assegnare ad un riferimento di una sottoclasse un oggetto della superclasse.

SOSTITUZIONE DI RIFERIMENTI

Dove è richiesta una superclasse posso sempre passare una sottoclasse.

Esempio

public void stampa (Auto a) {a.visualizza();

}

Taxi t = new Taxi(“AY 765 OP”, “NUM 3456”);Auto a = new Auto (“AD 098 TY”);stampa (a);stampa (t);

L’OPERATORE instanceof

L’operatore instanceof serve per determinare il tipo esatto di un oggetto. Ha come operandi un oggetto e una classe, restituisce un valore booleano.

Si può effettuare un’operazione di downcast verso il tipo corretto, se è necessario. Serve per poter invocare metodi specifici del tipo corretto.

Esempio:

if (c instanceof Taxi)((Taxi) c).setLicenza (“NUM 23425”);

POLIMORFISMO

Un riferimento ad oggetto può avere a runtime un tipo diverso di quello dichiarato, cioè può appartenere ad una sottoclasse del tipo dichiarato.

Quale metodo verrà chiamato dipende dal tipo effettivo di un oggetto: questo è il polimorfismo ed è possibile grazie al collegamento dinamico.

Il metodo che verrà chiamato non viene deciso al momento della compilazione del programma, ma a runtime.

ESEMPIO

Una collezione polimorfica.

Auto a[] = {new Auto(“AD 234 YT”),new Taxi (“AC 123 KJ”, “NUM 9876”) }

for (int i=0; i<a.length; i++)a[i].visualizza();

CLASSI ASTRATTE

Forniscono un’implementazione parziale di alcuni concetti.

Sono superclassi talmente generali, che vengono utilizzate solo come un framework per le sottoclassi.

Una classe astratta non può essere istanziata.

LA PAROLA RISERVATA abstract

Per dichiarare una classe astratta si usa la parola riservata abstract.

public abstract class Veicolo{

private String targa;public String getTarga() { return targa; }public void setTarga(String targa) {

this.targa = targa; }}……….public class AutoTreno extends Veicolo{

private int carico;…………

}

METODO ASTRATTO

E’ un metodo che non può essere implementato da una classe.

Fa parte di una classe astratta.

Deve essere implementato da una sottoclasse concreta (non astratta).

Ogni sottoclasse lo può implementare in maniera differente.

DEFINIZIONE DI METODI ASTRATTI

La classe deve essere abstract.

public abstract class Veicolo{

public abstract boolean collaudato();……

}Si stabilisce il nome del metodo, la lista dei parametri e il tipo del valore di ritorno.

Le sottoclassi concrete implementeranno o sovrascriveranno il metodo.

POLIMORFISMO

Si possono definire delle collezioni polimorfiche (tipi differenti) utilizzando le classi astratte.

Veicolo v[] = { new Auto();new Autocarro();

};

for (int i=0; i<v.length; i++)if (v[i].collaudato())

……

INTERFACCIA

Sono delle raccolte di comportamenti astratti (non implementati) che possono essere combinati in una qualunque classe al fine di aggiungere un comportamento non fornito dalle sue superclassi.

Esempio: il poter sterzare.

INTERFACCE

Le interfacce sono come classi completamente astratte.

Tutti i metodi sono astratti, cioè definiti come : public abstract.

Tuttte le variabili sono definite come : public static final.

Un’interfaccia definisce un insieme di metodi che possono essere implementati da altre classi.

Una classe può estendere una sola classe ma può implementare più interfacce.

DEFINIZIONE DI INTERFACCIA

Per definire un’interfaccia si utilizza la parola riservata interface.

public interface Guidabile{

int ANGOLO_MAX = 135;void giraDestra(int gradi);void giraSinistra(int gradi);

}

Metodi: public abstract

Proprietà: public static final

IMPLEMENTARE UN’INTERFACCIA

Clausola implements

public class Auto extends Veicolo implements Guidabile{

……public void giraDestra(int gradi) { … }public void giraSinistra(int gradi) { … }

}

Se un classe non implementa tutti i medoti di un’interfaccia deve essere dichiarata astratta.

POLIMORFISMO CON INTERFACCE

Quando faccio riferimento ad una classe che implementa una interfaccia, posso anche utilizzare l’interfaccia.

Guidabile g;

g può essere un riferimento a qualsiasi oggetto che appartiene ad una classe che implementa l’interfaccia Guidabile

void viaggia (Guidabile g){…….g.giraDestra(120);

}

USO DI instanceof

Può essere utilizzato per verificare se un oggetto implementa un’interfaccia.

public metodoA (Object obj){

if (obj instanceof Guidabile)((Guidabile)obj).giraSinistra(110);

}

ARRAY

Un array è un mezzo per contenere una serie di variabili dello stesso tipo.Un array è un oggetto, non è un tipo primitivo.Posso vederlo come un insieme di celle di memoria contigue, ognuna delle quali contiene un valore.Es. array di 5 interi

Un array può contenere tipi primitivi o oggetti.Ogni elemento dell’array può contenere un solo valore.

In Java le dimensioni degli array possono essere definite in fase di runtime.

311972

DEFINIZIONE DI ARRAY

E’ necessario dichiarare l’array utilizzando le parentesi quadre, posso metterle sia dopo il tipo che dopo il nome dell’array.

String[] nomi;String nomi[];

Bisogna quindi creare l’array con l’operatore new

nomi=new String[5];

L’operatore new inizializza i singoli valori dell’array come per gli attributi di istanza.Posso anche creare un’array assegnando a tutti i suoi componenti un valore

String[] nomi={“pippo”,”pluto”,”nonna papera”};

DEFINIZIONE DI ARRAY

Per accedere agli elementi dell’array bisogna specificarne la posizione all’interno delle parentesi quadre.

nomi[1]=”paperino”;System.out.println(nomi[3]);

Se devo creare degli array di oggetti, oltre ad applicare l’operatore new all’array, lo devo applicare anche ai singoli componenti dell’array, devo cioè creare i singoli oggetti che poi formano il mio array.

Auto[] mieAuto=new Auto[5];mieAuto[1]=new Auto();

ARRAY MULTIDIMENSIONALI

Un array multidimensionale è realizzato come array di array.Vediamo per esempio un array in due dimensioni, possiamo rappresentarlo come una matrice.

int [][] array=new int[4][5];

Posso creare anche un array mutidimensionale non regolare:

int[][] array=new int[5][];int cont=0;a[0]=new int[++cont];a[1]=new int[++cont];a[2]=new int[++cont];

STRINGHE

In java le stringhe sono degli oggetti, istanze della classe String.La classe String supporta solo stringhe costanti (non modificabili)

String str="test";

è equivalente a :

String str=new String("testo");

E’ il compilatore che sostituisce la seconda sintassi alla prima.Questo permette di avere una gestione più flessibile.Per concatenare le stringhe si usa l’operatore +

String s="";s=s+"a"+"b";

ASSEGNAMENTO DI STRINGHE

Che output produce il seguente codice?

public static void main(String[] args) {

String n,c;n="nome";c=n;

System.out.println(n+" - "+c);

n=n+" cognome";System.out.println(n+" - "+c);

}

STRINGHE

StringBuffer

La classe StringBuffer permette di gestire le stringhe variabili.

Il compilatore sostituisce automaticamente oggetti di tipo String con oggetti di tipo StringBuffer nei casi necessari.

String s=””;s=s+”a”+”b”;

viene sostituito con :

String s=””;s=new StringBuffer(””).append(”a”).append(”b”).toStrong();

E’ fondamentale utilizzare questa classe ogni volta che vengono fatte elaborazioni pesanti sulle stringhe.

CLASSI DI COPERTURA

I tipi primitivi non sono oggetti, quindi non possono essere passati come argomenti dove sono richiesti oggetti.Esistono delle classi di copertura (wrapper), una per ogni tipo primitivo.

BOXING E UNBOXING

Ogni classe wrapper definisce:• un costruttore che accetta il valore primitivo da incapsulare• un metodo che restituisce il valore primitivo incapsulato

• Per incapsulare un valore primitivo (BOXING)– Integer i = new Integer(valore int)– Double d = new Double(valore double)– Character c = new Character(valore char)

• Per estrarre il valore incapsulato (UNBOXING):– Integer fornisce il metodo intValue()– Double fornisce il metodo doubleValue()– Character fornisce il metodo charValue()

Integer i = new Integer(33); // boxingint k = i.intValue(); // unboxing

WRAPPER E OPERAZIONI

Le classi wrapper non hanno operatori aritmetici

new Integer(3) + new Integer(2); // ERRORE

Quindi, per operare su due valori incapsulati inoggetti wrapper, in linea di principio occorre:

– estrarre i valori incapsulati (unboxing)– svolgere le operazioni su essi,– costruire un oggetto per il valore risultato (boxing)

Integer z =new Integer(x.intValue() + y.intValue());

BOXING AUTOMATICO

In Java 1.5, boxing e unboxing di valori primitivi diventano automatici.

Quindi, ora si può scrivere:

Integer x = new Integer(ix);Integer y = new Integer(4);Integer z = x + y;

perché la conversione da Integer a int degli operandi (unboxing) e la successiva conversione del risultato in Integer (boxing) sono automatiche.

BOXING AUTOMATICO

Analogamente è quindi possibile inserire valori primitivi in strutture dati che accettano Object:

List l = new ArrayList();l.add(21); // OK in Java 1.5

perché viene attuata automaticamente la conversione daint a Integer (boxing) dal valore primitivo 21.

Fino a Java 1.4.2, avremmo invece dovuto scrivere:

l.add(new Integer(21));

facendo quindi esplicitamente l’operazione di boxing.

BigDecimal

Utilizzata in tutti i casi in cui è prevista una precisione specifica.

- costruttori che prevedono il valore in diversi formati ed eventualmente la precisione.

- metodi di conversione in altri formati e metodi operatori, eventualmente la precisione può essere impostata anche nei metodi operatori

- non esistono operatori tra questi oggetti, ma solo metodi

BigDecimal

Non è possibile fare questo:

BigDecimal b1=new BigDecimal(2);BigDecimal b2=new BigDecimal(3);BigDecimal b3=b1+b2; // ERRORE

Si possono solo usare metodi:

BigDecimal b3=b1.add(b2);

BigDecimal b4=b1.multiply(b2);

BigDecimal

Per impostare una precisione è necessario definire un MathContext

MathContext(int setPrecision)

E utilizzarlo nella costruzione degli oggetti e nelle operazioni

MathContext mc = new MathContext(2);BigDecimal b1=new BigDecimal(10,mc);BigDecimal b2=new BigDecimal(3,mc);BigDecimal b3=b1.add(b2);BigDecimal b4=b1.divide(b2,mc);

Nella divisione conviene sempre usarlo, altrimenti le divisioni che hanno un numero infinito di decimali non possono essere arrotondate e generano una eccezione

Object

La classe Object definisce una serie di metodi che possono essere ridefiniti all’interno delle classi figlie.

boolean equals(Object obj) Indicates whether some other object is "equal to" this one.

String toString() Returns a string representation of the object.

protected Object clone() Creates and returns a copy of this object.

Confronto tra oggetti

L’operatore == confronta correttamente i tipi primitivi.Per gli oggetti restituisce true se i due oggenti confrontati sono la stessa istanza.Per valutare se due istanze diverse sono uguali, è necessario utilzzare il metodo equals, ovviamente questo deve essere ridefinito nelle classi su cui si vuole utilizzare.

String a=”Stringa”;if(a.equals(”Stringa”)){

return true;}

Per le stringhe esiste anche il metodo :

public boolean equalsIgnoreCase(String anotherString)

Confronto tra oggetti

Cosa produce il seguente esempio?

String s1="ciao";String s2="ciao"; System.out.println(s1==s2);

s1=s1+s2;s2=s2+s2;

System.out.println(s1==s2);

Date

Per la gestione delle date esiste la classe java.util.DatePermette di memorizzare sia la data che l’ora

new Date();

Costruisce una data partendo dai millisecondi correnti.

Gli unici metodi utilizzabili sono after() before() compare()Tutti gli altri metodi sono deprecati.

Per gestire la costruzione e la manipolazione delle date deve essere utilizzata la classe Calendar, oppure nei casi più semplici la classe SimpleDateFormat

SimpleDateFormat

Permette di interpretare o di formattare le date.

SimpleDateFormat(String pattern)

String format(Date date) Date parse(String source)

Date d1=new Date();SimpleDateFormat sdf= new SimpleDateFormat("dd/MM/yyyy");System.out.println(sdf.format(d1));Date d2=null;try { d2 = sdf.parse("01/02/2010"); } catch (ParseException e) { e.printStackTrace();}

Calendar

Permette di manipolare le date.

Per ottenere una istanza di calendarCalendar cal=Calendar.getInstance();

Per valorizzare il calendar con la data specificavoid setTime(Date date)

Per eseguire operazioni sulle datevoid add(int field, int amount)

Per ottenere un campo della dataint get(int field)

Per settare un campo della datavoid set(int field, int value)

GESTIONE DEGLI ERRORI

Se un’operazione non può essere completata perché si è verificato un errore, il programma dovrebbe:

Tornare in uno stato normale e consentire all’utente di eseguire altri comandi, oppure

Salvare il lavoro e terminare il programma in modo appropriato

Il compito di un gestore di eccezioni consiste nel trasferire il controllo dal punto in cui si è verificato l’errore ad un punto che sia in grado di risolvere o gestire l’errore.

POSSIBILI ERRORI

•Errori di input da parte dell’utente

•Errori provocati da dispositivi

•Limiti fisici

•Errori nel codice

GESTIONE TRADIZIONALE DEGLI ERRORI

Nei linguaggi precedenti, le funzioni in cui si può verificare un errore, restituiscono un valore indicante l’errore (-1), è quindi la parte di codice che chiama la funzione che deve controllare se si è verificato un errore ed eventualmente segnalarlo a monte.

Problemi:

• il valore di errore (-1) può essere un valore valido

• il codice risulta di difficile lettura

ECCEZIONI

I metodi di Java generano un’eccezione se per qualche ragione falliscono il loro scopo.

L’eccezione è un oggetto, e quando viene generato viene messo in cima allo stack delle chiamate.

Quindi, il metodo viene interrotto e la VM cerca nello stack delle chiamate un metodo che sia in grado di gestire quel particolare tipo di eccezione.

GERARCHIA ECCEZIONI

ECCEZIONI

Error descrivono gli errori interni del sistema run-time di Java, non devono essere gestiti.

Le Runtime Exception derivano da errori di run-time come: errata conversione di tipo, accesso errato ad un array ... , non dovrebbero essere gestite, dovrebbe essere applicata una gestione preventiva.Queste eccezioni sono dette unchecked e non vengono controllate a compile time

Tutte le altre eccezioni vanno gestite.Sono detta checked e sono controllate a compile time, per questo devono obbligatoriamente essere gestite.

ERROR

RUNTIME EXCEPTION

EXCEPTION

CATTURARE LE ECCEZIONI

Se si chiama un metodo che può generare un’eccezione, bisogna fare in modo che questa eccezione possa essere gestita, per fare questo si usa la seguente struttura:

try {// codice che può generare l’eccezione

}catch (tipo_di_eccezione_1) {// codice del gestore dell’eccezione

}

Quando si verifica un’eccezione all’interno del try, questa viene rilevata e se è del tipo indicato nel catch, il controllo viene passato al relativo codice. Quindi il controllo passa alla riga di codice successiva alla fine del catch.

ECCEZIONI MULTIPLE

E’ possibile che un metodo generi più di una eccezione, in questo caso bisogna aggiungere tante clausole catch quanti sono i tipi di eccezioni che vanno gestiti :

try {// codice che può generare l’eccezione

}catch (tipo_di_eccezione_1 e1) {// codice del gestore dell’eccezione 1

}catch (tipo_di_eccezione_2 e2) {// codice del gestore dell’eccezione 2

}

Se più eccezioni derivano dalla stessa classe, possiamo raccoglierle e gestire solamente la superclasse.

CLAUSOLA FINALLY

Se vogliamo che una parte del codice venga eseguita comunque, anche nel caso in cui vengano generate delle eccezioni, bisogna inserire la clausola finally:

try {// codice che può generare l’eccezione

}catch (tipo_di_eccezione_1) {// codice del gestore dell’eccezione 1

}finally {// codice sempre eseguito

}

E’ importante notare che finally non è una clausola per gestire tutte le eccezioni che non sono gestite dalle singole catch.

GESTIONE DELLE ECCEZIONI

La struttura try-catch gestisce localmente le eccezioni, cioè all’interno del metodo in cui si sono verificate.

E’ possibile non gestire l’eccezione a questo livello e passarla al metodo che aveva chiamato il metodo in questione.

Per fare questo, i metodi che vogliono passare le eccezioni, devono dichiarare che tipo di eccezioni possono restituire tramite la parola chiave throws :

public void metodo1() throws tipo_di_eccezione{// codice del metodo

}

In questo modo la gestione delle eccezioni risale la gerarchia dei metodi dello stack.

GENERARE ECCEZIONI

Un metodo deve dichiarare che al suo interno può aver luogo una eccezione, la sintassi è la stessa del caso precedente.

Per generare un’eccezione, bisogna utilizzare la parola chiave throw.In questo modo, in qualunque parte del codice si può generare un’eccezione.

Prima di essere “lanciata”, essendo un oggetto, l’eccezione va sempre creata con una new.

throw new IOException();

oppure

IOException eccez=new IOException();throw eccez;

CREARE CLASSI ECCEZIONI

Devono estendere la classe Exception o le sue sottoclassi.Solitamente le classi eccezioni hanno due costruttori, uno di default e uno con il messaggio di errore.

class MiaEccezione extends IOException{public MiaEccezione() {}public MiaEccezione(String msg){

super(msg);}

}

void mioMetodo(DataInput in) throws MiaEccezione{// codiceif(condizione_di_errore)

throw new MiaEccezione();}

GESTIONE COMBINATA DELLE ECCEZIONI

A volte è necessario gestire localmente l’eccezione e nello stesso tempo propagarla al metodo chiamante, questo meccanismo può essere realizzato catturando l’eccezione localmente, e quindi rigenerando l’eccezione che passa al metodo chiamante.

void metodoChiamante() throws MiaEccezione{try{

mioMetodo(mioDataInput)} catch (MiaEccezione e){

System.out.println(e.getMessage());// gestione locale dell’eccezionethrow new MiaEccezione(e.getMessage()); // propaga l’eccezione al chiamante

}}

ECCEZIONI : LINEE GUIDA

• Utilizzarle solo nei casi che sono al di fuori di un possibile controllo

• Non usare blocchi catch che non fanno nulla

try {// codice

} catch(MiaEccezione e) { …}

Non accomunare tutte le eccezioni sotto un'unica classe, gestirle separatamente

try{// codice

} catch(Exception e) { … }

JAVA COLLECTION FRAMEWORK

Interfacce fondamentali (package java.util)• Collection: nessuna ipotesi su elementi duplicati o relazioni d’ordine• List: introduce l’idea di sequenza• Set: introduce l’idea di insieme di elementi (quindi, senza duplicati)• SortedSet: l'insieme ordinato• Map: introduce l’idea di mappa, ossia di funzione che associa chiavi (identificatori univoci) a valori• SortedMap: la mappa ordinataCriteri-guida per la definizione delle interfacce:• Minimalità – prevedere solo metodi davvero basilari…• Efficienza – …o che migliorino nettamente le prestazioni

JAVA COLLECTION FRAMEWORK

Implementazioni fondamentali• per le liste: ArrayList,LinkedList, Vector• per le tabelle hash: HashMap, HashSet, Hashtable• per gli alberi: TreeSet, TreeMap

JAVA COLLECTION FRAMEWORK

COLLECTION - SET

boolean add(E e) Adds the specified element to this set if it is not already present (optional operation).boolean contains(Object o) Returns true if this set contains the specified element.boolean isEmpty() Returns true if this set contains no elements.Iterator<E>iterator() Returns an iterator over the elements in this set.boolean remove(Object o) Removes the specified element from this set if it is presentint size() Returns the number of elements in this set (its cardinality).

LIST

void add(int index, E element) Inserts the specified element at the specified position E get(int index) Returns the element at the specified position in this list.int indexOf(Object o) Returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element.int lastIndexOf(Object o) Returns the index of the last occurrence of the specified element in this list, or -1 if this list does not contain the element.E remove(int index) Removes the element at the specified position in this list E set(int index, E element) Replaces the element at the specified position in this list with the specified element

MAP

boolean containsKey(Object key) Returns true if this map contains a mapping for the specified key.boolean containsValue(Object value) Returns true if this map maps one or more keys to the specified value. V get(Object key) Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key. V put(K key, V value) Associates the specified value with the specified key in this map V remove(Object key) Removes the mapping for a key from this map if it is present

ITERATORI

Un iteratore è una entità capace di garantire l'attraversamentodi una collezione con una semantica chiara e ben definita (anche se la collezione venisse modificata)

public interface Iterator {boolean hasNext();Object next();void remove(); // opzionale

}

Di fatto, un iteratore offre un metodo next per esplorare uno ad uno gli elementi della collezione: il metodo hasNext permette di sapere quando non ci sono più elementi.Per ottenere un iteratore su una qualsiasi collezione, basta chiamare l'apposito metodo iterator()

JCF: L'ORDINAMENTO

L'ordinamento è supportato in SortedSet e SortedMap– SortedSet è usato tipicamente per elenchi di parole, di iscritti, etc.– SortedMap è usata tipicamente per elenchi telefonici, agende e più in generale quando vi sono chiavi univoche associate a valori ordinati.

Ci sono due modi per ordinare oggetti:

• l'interfaccia Comparable dichiara il metodo per definire l'ordinamento naturale in senso ascendente• l'interfaccia Comparator (più complessa) dichiara un insieme di metodi che permettono di avere completo controllo sulle politiche di ordinamento degli oggetti.

LA CLASSE FACTORY Collections

Collections è una classe factory, che comprende • metodi statici per lavorare con collezioni• funzioni che implementano algoritmi utili(in particolare, ordinamento e ricerca binaria)

• sort(List): ordina una lista con l'algoritmo "merge sort"• shuffle(List): permuta casualmente gli elementi della lista• reverse(List): inverte l'ordine degli elementi della lista• fill(List,Object): rimpie la lista col valore dato• copy(List dest,List src): copia la lista sorgente nell'altra• binarySearch(List,Object): cerca l'elemento dato nellalista ordinata fornita, usando un algoritmo di ricerca binaria.

JCF "CLASSICA": PROBLEMI

Usare il tipo generico Object per definire contenitori generici causa non pochi problemi– equivale ad abolire il controllo di tipo– rende possibili operazioni sintatticamente corrette ma semanticamente errate– determina quindi il rischio di errori a runtime pur a fronte di compilazioni formalmente corrette– la correttezza è affidata a "commenti d'uso!!– rende il linguaggio non "type safe“

• Java 1.5 introduce un nuovo approccio, basatosul concetto di TIPO PARAMETRICO ("generici")

GENERICS

• È sbagliato abolire il controllo di tipo!

•Occorre un altro modo per esprimere genericità,che consenta un controllo di tipo a compile time– type safety: "se si compila, è certamente corretto“

• Java 1.5 introduce i tipi parametrici ("generici")

• Il tipo può essere un parametro:– in funzioni statiche, in classi e metodi di classi– notazione <TIPO>

• Si possono definire relazioni fra "tipi generici"

ESEMPIO

Senza GenericsList thingList = new ArrayList();thingList.add( aThing );Thing t = (Thing) thingList.get( 0 );thingList.add( notAThing );Thing t2 = (Thing) thingList.get( 1 ); // exception

Con GenericsList<Thing> thingList = new ArrayList<Thing>();thingList.add( aThing );Thing t = thingList.get( 0 ); // no cast neededthingList.add( notAThing ); // compile error

JAVADOC

Javadoc estrae informazioni relative a: • pacchetto• classe pubblica• interfaccia pubblica • metodo pubblico o protetto• variabile pubblica o protettaI commenti cominciano con /** e terminano con */ , ogni riga intermedia deve cominciare con *All’interno dei commenti si possono inserire tag Html come per esempio<b> </b> per il grassetto<i> </i> per il corsivo<tt> </tt> per un font a spaziatura fissa<img ..> per una immagine

Tag Javadoc

@see <nome classe>Crea un link ad un’altra classe

@see <nome classe>.<nome metodo>Crea un link ad un metodo di un’altra classe

@version <testo>Inserisce informazioni sulla versione

@author <nome>Inserisce il nome dell’autore

@since <versione>Indica da che versione l’oggetto esiste

Tag Javadoc

@param <nome parametro> <descrizione>Permette di descrivere un parametro di un metodo

@return <descrizione>Permette di descrivere il valore di ritorno di un metodo

@exception <eccezione> <descrizione>@throws <eccezione> <descrizione>

Permettono di descrivere una eccezione lanciata nel metodo

@deprecatedIndica un metodo deprecato e ne descrive il motivo

THREAD E PROCESSI

Multitasking: la capacità di un computer (S.O.) di eseguire più lavori contemporaneamente. Diversi processi in esecuzione allo stesso tempo.

Multithreading: ogni programma può eseguire contemporaneamente diverse sezioni del programma, tali sezioni sono dette percorsi (thread).

I thread possono condividere la stessa area dati.

THREAD

Programma multithread serve per eseguire più task in parallelo.

Thread: percorso in esecuzione all’interno di un programma.

Il Sistema Operativo coordina l’esecuzione dei thread (scheduling).

Ogni thread ha il suo stack e il proprio insieme di registri virtuali.

CLASSE Thread

Java definisce a livello di linguaggio il funzionamento dei thread.

La classe Thread mantiene lo stato del thread, definisce metodi per controllare i thread.

Si deve instanziare un oggetto della classe Thread per ogni thread.

CICLO DI VITA DI UN THREAD

new -> thread allocato in memoria

start() -> il thread diventa running

stop() -> il thread è terminato (o fine run())

suspend(), sleep(), wait() -> il thread è bloccato

resume(), notify() -> il thread è pronto per ripartire.

CREARE UN THREAD

Definire una sottoclasse della classe Thread.

Overriding del metodo run()

Creare un’istanza della sottoclasse prima definita.

Invocare il metodo start() dell’istanza creata.

INTERFACCIA Runnable

Serve per rendere thread istanze di una classe che non deriva dalla classe Thread.

Per lanciare un thread di una classe che implementa Runnable devo creare un nuovo oggetto Thread passandogli come argomento il mio oggetto Runnable

class MyClass implements Runnable …Thread t1=new Thread(new Myclass());t1.start()

Il costruttore Thread (Runnable r).

Invocare start() di Thread per chiamare il nostro run().

CONTROLLO DI UN THREAD

Il metodo suspend() serve a bloccare l’esecuzione di un thread.

Il metodo resume() serve a far riprendere l’esecuzione di un thread.

Il metodo sleep(long millis) serve ad interrompere l’esecuzione di un thread per un determinato intervallo di tempo.

Il metodo join() attende la fine del thread.

Il metodo isAlive() testa se il thread non è terminato.isAlive().

PROBLEMI DEI THREAD

Accesso a risorse condivise (thread unsafe/safe).

Monitor: oggetto che applica il principio della mutua esclusione.

Modificatore synchronized per i metodi: su un oggetto il metodo può essere invocato da un solo thread alla volta.

Lo statement synchronized, ad esempio per un array, che non ha metodi.

Synchronized (expression) Statement

Java non gestisce i deadlock.

SINCRONIZZAZIONE

I monitor (synchronized) possono anche servire per coordinare il funzionamento dei thread.

Il metodo wait(), della classe Object, permette ad un oggetto di rilasciare il monitor e di mettersi in attesa di una notifica.

Il metodo notifyall(), della classe Object, permette ad un oggetto di notificare a tutti i thread che si sono messi in attesa che possono riprendere l’esecuzione.