Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
vuoi
o PayPal
tutte le volte che vuoi
NON SI USA MAI L’OPERATORE == PER CONFRONTARE DUE
STRINGHE!!! Se si usasse, la veridicità del confronto sembrerebbe
essere assegnata in maniera casuale. Ciò dipende da come è stata
progettata la JVM.
Difatti, bisogna ricordare che le stringhe sono oggetti, pertanto le
variabili di tipo String contengono il riferimento in memoria
dell’oggetto stringa. Quindi se facessimo:
String s1 = “Ciao”;
String s2 = s1;
String s3 = “Cia”;
S3 = s3 + “o”; //s3 contiene “Ciao”
E decidessimo di confrontare le stringhe, avremmo:
- s1 == s2 vero perché puntano allo stesso oggetto stringa;
- s1 == s3 FALSO perché puntano ad oggetti diversi, anche
se il contenuto della stringa è lo stesso.
È possibile anche stabilire l’ordinamento lessicografico di due
stringhe utilizzando il metodo compareTo() if(s1.compareTo(s2) <
0) …
25
Il metodo compareTo() restituisce un valore int:
- negativo se s1 precede s2 nell’ordinamento;
- positivo se s1 segue s2 nell’ordinamento;
- zero se s1 e s2 sono identiche.
Diciamo che il metodo compareTo() funziona come una sorta di
dizionario, e segue le seguenti regole:
- i numeri precedono le lettere;
- le lettere maiuscole precedono tutte le lettere minuscole;
- il carattere di “spazio bianco” precede tutti gli altri caratteri
Per confrontare oggetti si usa sempre il metodo equals() definito
nella classe Object (così come per le stringhe, che di fatto sono
oggetti!). NON si usa l’operatore == per lo stesso motivo per cui
non si usa per le stringhe, essendo anch’esse oggetti.
NB! VISIBILITA’ DELLE VARIABILI NEGLI IF:
OPERATORI BOOLEANI servono a svolgere operazioni su valori
booleani:
- l’operatore && dà come risultato vero se e solo se tutte le
condizioni sono vere;
- l’operatore || dà come risultato vero se e solo se almeno una
delle condizioni è vera;
- l’operatore ! inverte il valore di un’espressione booleana.
NB! in java la valutazione di un’espressione con valori booleani
viene effettuata con una strategia chiamata cortocircuito, che
26
consiste nel valutare l’espressione (quindi dire il risultato: true o
false) appena è possibile decidere il risultato stesso.
Es.: se x = 20 e abbiamo:
if((x >= 0 && x <=30) || x > 40)…
l’ultima condizione non viene considerata proprio perché
l’espressione è sicuramente vera dato che la prima condizione è
vera.
Precedenza dei valori booleani in ordine !, &&, ||.
Attenzione: esempio: if(0 <= x <= 1)… NON FUNZIONA! Il
compilatore si trova a dover applicare il primo operatore di tipo
boolean (che deriva da 0 <= x) con il secondo operatore di tipo int:
sarebbe come fare l’operazione false (o true) <= 1 non si può
fare, il compilatore dirà che l’operatore <= non può essere
applicato ad un tipo boolean.
ENUNCIATO SWITCH confronta un’unica variabile con diverse
alternative.
Vantaggio non bisogna ripetere il nome della variabile da
confrontare;
Svantaggio si può utilizzare lo switch se la variabile da
confrontare è di tipo int, byte, short, char, od oggetti String. Per gli
altri tipi di dati lo switch NON si può usare;
Svantaggio non si può usare se uno dei valori da confrontare non
è costante;
Svantaggio ogni case deve terminare con un break, altrimenti
vengono eseguiti anche i case successivi!
ENUNCIATO WHILE se hai qualche dubbio consulta il pp 04
confronti cicli!
ENUNCIATO FOR se hai qualche dubbio consulta il pp 04
confronti cicli!
27
VARIABILI NON INIZIALIZZATE se in un programma viene
definita una variabile, ma non viene inizializzata, lo spazio di
memoria in questione contiene un valore “casuale” (contiene
l’ultimo valore attribuito a quello spazio di memoria, che a noi non è
noto). Questo problema provoca errori di esecuzione in molti
linguaggi di programmazione, ma il compilatore java segnala come
errore l’utilizzo di variabili a cui non sia mai stato assegnato un
valore: questi errori sono logici, non sintattici, ma vengono
comunque individuati dal compilatore perché si tratta di errori
semantici che sono individuabili automaticamente.
ERRORI E CONSIGLI SUI CICLI vedi pp 04, rileggi da slide 82 a
86!
CLASSI DI UTILITA’ Le classi che non servono a creare oggetti,
ma contengono metodi statici e costanti si chiamano classi di utilità
(es. classe Math).
VARIABILI STATICHE immaginiamo di voler modificare la classe
BankAccount in modo tale che il suo stato contenga anche un
numero di conto e:
28 - ogni numero di conto sia assegnato dal costruttore;
- ogni conto deve avere un numero diverso;
- i numeri assegnati devono essere progressivi, iniziando da 1.
SOLUZIONE VERA serve una variabile che sia condivisa da tutti gli
oggetti della classe. Una variabile di questo tipo si ottiene tramite la
dichiarazione static:
sintassi: private static int lastAssignedNumber;
NE ESISTE UN’UNICA COPIA indipendentemente da quanti oggetti
siano stati creati.
Ogni metodo o costruttore di una classe può accedere alle variabili
statiche della classe e modificarle.
Ecco un esempio di costruttore che funziona:
Notiamo che le variabili statiche NON possono essere inizializzate
all’interno dei costruttori. Perché? Perché altrimenti il loro valore
29
verrebbe inizializzato ogni volta che si crea un nuovo oggetto,
perdendo di fatto la sua utilità.
NB! le variabili static DEVONO essere PRIVATE proprio per evitare
accessi indesiderati.
CICLO DI VITA DI UNA VARIABILE In java esistono 4 categorie
di variabili:
- variabili locali (all’interno di un metodo);
- variabili parametro (chiamate parametri formali);
- variabili di esemplare;
- variabili statiche.
Ovviamente hanno in comune il fatto di contenere valori di un tipo
ben preciso, ma differiscono per il loro ciclo di vita, cioè il periodo di
tempo in cui continuano a occupare lo spazio in memoria che gli è
stato assegnato.
Una variabile locale:
- viene creata quando viene eseguito l’enunciato in cui è
definita;
- viene eliminata quando l’esecuzione del programma esce dal
blocco di enunciati in cui la variabile è definita.
Una variabile parametro:
- viene creata quando viene invocato il metodo;
- viene eliminata quando l’esecuzione del metodo termina.
Una variabile statica:
- viene creata quando la JVM carica la classe per la prima volta;
- viene eliminata quando la classe viene scaricata dalla JVM.
Una variabile di esemplare:
- viene creata quando viene creato l’oggetto a cui appartiene;
- viene eliminata quando l’oggetto viene eliminato.
Un oggetto è inutilizzabile quando non esiste più un riferimento ad
esso. La JVM effettua automaticamente la gestione di memoria
durante l’esecuzione di un programma, viene riciclata, cioè resa
libera da oggetti che non hanno più un riferimento nel programma.
ALLOCAZIONE DELLA MEMORIA IN JAVA A ciascun
programma, al momento dell’esecuzione, viene dedicata un’area di
memoria:
30 - una parte di essa serve a memorizzare il codice. Quest’area è
statica;
- La java Stack è un’area dinamica in cui vengono memorizzati i
parametri e le variabili locali;
- La java Heap è un’area dinamica in cui vengono creati oggetti
durante l’esecuzione dei metodi di un programma, usando
l’operatore new.
VISIBILITA’ DELLE VARIABILI per evitare problemi dobbiamo
conoscere l’ambito di visibilità di ogni tipo di variabile (ovvero dove
è visibile nel programma). Ad esempio, se una variabile viene
inizializzata in un if, la sua visibilità è limitata al corpo dell’if stesso.
Notiamo che:
- Variabili private hanno visibilità di classe, ovvero hanno
visibilità solo all’interno della classe in cui sono definite;
- Variabili public hanno visibilità anche al di fuori della classe;
- Non è necessario qualificare i membri (variabili e metodi)
appartenenti alla stessa classe perché ci si riferisce
automaticamente al parametro implicito this.
Esempio:
VISIBILITA’ SOVRAPPOSTE esempio:
31
Risposta: NO. Java specifica che in casi come questo prevale la
variabile LOCALE, mentre la variabile di esemplare viene “messa in
ombra” (SHADOWED): questa scelta è giustificata dal fatto per cui
una variabile di esemplare può sempre essere qualificata usando il
parametro this.
CHIAMATE PER VALORE E RIFERIMENTO a volte si dice
impropriamente che in java i numeri sono passati per valore e gli
oggetti per riferimento. In realtà il passaggio è sempre per valore,
infatti:
- Passando per valore una variabile oggetto, si passa una copia
del riferimento, il quale è contenuto nella variabile oggetto
stessa;
- Questo consente di modificare lo stato dell’oggetto stesso,
come avviene con il passaggio “per riferimento”.
Curiosità: altri linguaggi (come C++) consentono il passaggio per
riferimento rendendo possibile la modifica dei parametri effettivi.
ERRORI TIPICI CON I COSTRUTTORI Si potrebbe pensare che
invocare il costruttore su un oggetto già costruito per farlo tornare
alle condizioni iniziali possa funzionare, in realtà no! Bisogna
ricordare che un costruttore può essere invocato SOLO con
l’operatore new quindi bisogna eseguire un codice del tipo:
BankAccount account = new BankAccount();
32
account.deposit(500); // modifico account
account = new BankAccount(); // rimetto account alle condizioni
iniziali
PACCHETI Tutte le classi della libreria standard sono raccolte in
pacchetti (package) e sono organizzate per argomento e/o finalità.
Per usare una classe di una libreria bisogna importarla secondo la
sintassi: import nomePacchetto.NomeClasse;
Le classi System e String sono importate automaticamente e
appartengono al pacchetto java.lang
Con la sintassi: import nomePacchetto. *; si importano tutte le
classi di un pacchetto.
Attenzione import java.util. *;
import java.swing. *;
In questo modo, ad esempio, la classe Timer appartiene ad
entrambi i pacchetti, quindi se definisco una variabile oggetto di
tipo Timer, il