vuoi
o PayPal
tutte le volte che vuoi
LINGUAGGIO DI PROGRAMMAZIONE JAVA.
Introduzione.
Il linguaggio principale della programmazione ad oggetti è Java. Sviluppato dallo Java
Community Process (o JCP), venne ideato nel 91 dalla Sun per poi diventare di
proprietà della Oracle. Per poter funzionare ha bisogno di vari strumenti e di una
libreria di classi predefinita che contiene varie migliaia di classi e metodi. La
piattaforma è organizzata in più livelli: lo JavaSE (o Java 2 Standard Edition) utile
per le applicazioni desktop e lo JavaEE (o Java 2 Enterprise Edition) utile per le
applicazioni per i server. Ognuno dei livelli si compone di una serie di specifiche (JSR),
una serie di strumenti, una serie di librerie o API (Application Program Interfaces).
Java è un linguaggio semi-interpretato in quanto il suo codice sorgente viene
trasformato in un linguaggio intermedio noto come Bytecode per poter essere
eseguito dalla Java Virtual Machine (o JVM). Questa permette di eseguire i
programmi Java, interpretandoli, ma solo se questi sono già trasformati in codice
bytecode. L’interpretazione è un modo alternativo alla compilazione e questo è
possibile grazie ad un interprete. Un componente fondamentale è il Just In Time
Compiler (o JIT Compiler) che analizza i pezzi di bytecode e li compila al volo in
codice oggetto. Ma ci sono anche altri componenti fondamentali come il Java
Runtime Environment (o JRE) che fornisce l’ambiente utile per usare la JVM e che
contiene le API di J2SE però non fornisce gli strumenti di sviluppo. Questi vengono
forniti dal Java Development Kit (o JDK) che contiene tutti gli strumenti di sviluppo
necessari per produrre applicazioni Java.
Classi e oggetti.
Per Java ci sono vari elementi comuni: variabili, costanti, tipi di dato, espressioni,
assegnazioni, lettura, stampa, strutture di controllo e i sottoprogrammi. Le
variabili sono dati salvati in uno spazio di memoria che devono essere prima
dichiarate e poi inizializzate. Per dichiarare una variabile bisogna specificare il tipo
di dato e darle un identificatore. Per inizializzare una variabile, invece, bisogna scrivere
il nome della variabile e assegnarle un valore o un’espressione con il segno uguale.
Per quanto riguarda i tipi di dato, Java fornisce un insieme di tipi di dato già definiti e
pronti all’uso noti come tipi primitivi: byte, short, int, long, float, double,
boolean, char. È possibile passare da un tipo all’altro tramite il casting, tuttavia non
può essere sempre effettuata. Per creare una costante useremo il qualificatore final
che stabilisce che la risorsa è immutabile. Le costanti sono globali e pubbliche (public
static). Per quanto riguarda le stringhe, queste sono un oggetto della classe
java.lang.String e vengono create con l’operatore new, tuttavia si possono creare
anche scrivendo String, nome della stringa e la parola o frase da assegnargli. Il primo
metodo crea un oggetto vero e proprio. Il secondo controlla se esiste già una stringa
simile e se questa esiste ritorna un riferimento ad essa altrimenti ne crea una nuova.
Le strutture di controllo sono uguali a quelle del C++ e per interrompere l’esecuzione
di questi cicli useremo break e continue. Le liste di valori associati ad una variabile
(anche note come array) sono un insieme di elementi dello stesso tipo. Questo viene
dichiarato specificandone la dimensione e per farlo bisogna specificare il tipo di dato
seguito dalle parentesi quadre, dargli un nome, scrivere l’operatore new e
successivamente riscrivere il tipo dell’array con la lunghezza del vettore. Gli array
sono di due tipi: monodimensionale e multidimensionali (formati da elementi che
altro non sono che array). Nei linguaggi di POO, il sistema viene suddiviso in
componenti logici (salvati nella memoria heap) che interagiscono tra di loro: classi e
oggetti. Ogni componente ha un nome, delle proprietà, dei metodi. Le proprietà
sono dei dati, che possono essere costanti o variabili, che rappresentano lo stato del
componente. I metodi, invece, sono funzioni o procedure che rappresentano quello
che il componente può fare. Nella zona di memoria del codice è contenuto il
bytecode, nello stack sono contenuti i record di attivazione dei metodi (variabili locali
e parametri), mentre lo heap è la zona di memoria riservata ai componenti. Una
classe rappresenta un gruppo di elementi di dati con funzioni associate che possono
eseguire operazioni su tali dati e si definisce tramite la parola chiave class. All’interno
di una classe sono presenti metodi e variabili. All’interno di un codice Java ci può
essere al massimo una classe pubblica (public) e con la prima iniziale maiuscola. Per
la rappresentazione grafica ci baseremo sulla convenzione UML (o Uniform
Modeling Language). La parola chiave che distingue i metodi e le proprietà di una
classe è static. Un metodo statico particolare è il metodo main. Esistono tre tipi di
classi: le classi che non eseguono metodi statici; le classi che non eseguono
costruttori; le classi che eseguono entrambi. La classe come componente è un
componente dell’applicazione di tipo classe; la classe come tipo di uno o più
oggetti è una struttura di una collezione di oggetti; la classe come unità di codice
sorgente è un file di codice sorgente che descrive la classe. I componenti vengono
organizzati all’interno dei package, un gruppo di componenti affini tra loro. Questo
compie due funzioni principali: completa il riferimento alle classi e stabilisce legami
più stretti tra i componenti di un package. Il suo nome può essere semplice o
composto con i nomi separati dal punto. Java fornisce diversi package tuttavia
possiamo creare anche un nostro pacchetto utilizzando la keyword package. Per
utilizzare una classe che appartiene ad un altro pacchetto useremo la keyword import
con il nome del pacchetto da importare. Questa può riferirsi ad una classe
specifica oppure riferirsi ad un intero package (*). Tutte le classi devono
appartenere ad un package, se il programmatore non ne specifica uno, il compilatore
assegna la classe ad un package implicito ovvero una cartella in cui il file della
classe è posizionato. Non tutte le proprietà e tutti i metodi sono visibili all’esterno di
quella classe. Per questo useremo i modificatori di visibilità dove i principali valori
sono public e private. Il primo stabilisce che tutti gli altri componenti possono usare
quella risorsa, il secondo stabilisce che la risorsa può essere utilizzata solo all’interno
del codice del componente stesso ed è inaccessibile all’esterno. I messaggi sono di
due tipi: inviati per richiedere l’esecuzione di un metodo e inviati per richiedere
l’accesso ad una proprietà. Gli oggetti sono un componente creato da un componente
classe e per questo viene chiamato anche istanza della classe. Una classe può
creare un numero arbitrario di oggetti e quelli che vengono creati da una stessa classe
hanno caratteristiche simili in quanto dello “stesso tipo”. Un oggetto ha proprietà e
metodi e tutti gli oggetti della stessa classe hanno le stesse capacità. Un oggetto ha
un identificatore, un insieme di proprietà e un insieme di metodi. L’identificatore di
oggetto (o OID) è un codice numerico che corrisponde all’indirizzo dell’oggetto nello
heap. La creazione di un oggetto è un servizio fondamentale offerto dalle classi ed
equivale ad eseguire un metodo particolare della classe chiamato costruttore. Il
costruttore è un metodo che genera in memoria un oggetto e ne restituisce
l’identificatore. Ha come nome quello della classe di appartenenza, deve essere public
e statico, può avere o meno dei parametri. Quando è senza parametri parliamo di
costruttore no-arg che può contenere o meno delle istruzioni. Se un costruttore non
contiene delle istruzioni parliamo di costruttore standard. Il costruttore viene
invocato in automatico con l’utilizzo della parola chiave new. Le classi devono avere
almeno un costruttore e quando ce ne sono più di uno si può verificare un fenomeno di
sovraccarico. Se il programmatore non ne specifica nessuno, il compilatore ne
aggiunge uno standard in automatico. Se una classe ha più di un costruttore dovranno
distinguersi sulla base del prototipo altrimenti si verifica il sovraccarico. Questi
costruttori avranno, pertanto, dei parametri. Per manipolare gli oggetti vengono usate
le variabili di riferimento che assumono come valore l’identificatore dell’oggetto.
Queste fungono da intermediario verso l’oggetto e possono essere di tre tipi: valore
indefinito, riferimento ad oggetto di tipo opportuno e variabile istanziata al
riferimento nullo. Quando si ha valore null vuol dire che la variabile non è collegata
a nessun oggetto. La parola this viene utilizzata per riferirsi agli attributi o metodi
locali. I riferimenti sono tipati, ogni variabile di riferimento può contenere solo
riferimenti ad oggetti di una classe specifica. Un riferimento non è un oggetto ma una
variabile di un tipo assimilabile ad un tipo primitivo e quindi viene dichiarata in modo
ordinario: se si tratta di una variabile locale la memoria relativa è lo stack ma
mantiene il valore di un identificatore di oggetto (heap). L’operazione principale è
quella di inviare due tipi di messaggi ad un oggetto: la richiesta di esecuzione di un
metodo e la richiesta di utilizzo di una proprietà.
Sintassi e semantica.
Molti elementi della sintassi di Java sono comuni a quelle del C++. Come ad esempio
la sensibilità alle maiuscole, il punto e virgola alla fine delle istruzioni, le
parentesi graffe per delimitare i blocchi di istruzioni, i commenti, gli
identificatori ecc. I dati in Java si dividono in due categorie: le componenti (classi e
oggetti) e i dati dei tipi primitivi (costanti, variabili, parametri che sono del tutto
analoghi a quelli della programmazione procedurale). In Java ci sono due tipi di
variabili: le variabili dei tipi primitivi e le variabili di riferimento. Le prime hanno
spazio nella memoria identificato da un nome, la cui natura è stabilita dal tipo e
inizialmente il valore è indefinito. Le seconde sono di tipo riferimento ad una classe.
Vengono pertanto utilizzate come intermediarie per gli oggetti della classe. Queste
sono tipate e inizialmente il valore è indefinito. Le costanti simboliche vengono create
con il modificatore final e hanno spazi nella memoria a cui viene assegnato un valore
che non può essere cambiato e possono essere dei tipi di base oppure di tipo di
riferimento. Le espressioni sono identiche al C++ e anche in Java esistono delle
funzioni predefinite appartenenti alla classe java.lang.Math come per le radici, le
potenze, il coseno, seno ecc. Inoltre, la classe Math definis