Lezione 1: introduzione al corso Java
Breve presentazione del corso
Questo corso è stato progettato con un obiettivo preciso: fornire gli elementi per apprendere un linguaggio di programmazione. Gli obiettivi principali di questo corso sono descritti di seguito:
- Presentare il materiale un passo alla volta, per consentire di assimilare facilmente ogni concetto prima di passare a un nuovo argomento. La presentazione delle varie caratteristiche è stata ordinata accuratamente in modo che ciascun argomento sia esposto nella sua interezza prima di vederlo in azione. Naturalmente questo non è sempre possibile: in questi casi, è fornita una breve descrizione introduttiva.
- Ricorrere a esempi quanto più semplici e brevi possibili. Questo approccio talvolta impedisce di affrontare problemi derivati dal mondo reale; tuttavia, il principiante trova più gratificante riuscire a capire ogni dettaglio di un esempio, che non essere impressionato dall’ampiezza del problema che viene risolto. Bisogna anche tenere conto di un serio limite alla quantità di codice che può essere assimilato in aula. Per questa ragione l’autore si aspetta di ricevere critiche per i suoi “esempi giocattolo”, ma è pronto ad affrontarle per realizzare un prodotto utile anche dal punto di vista pedagogico.
- Fornire le competenze importanti ai fini della comprensione del linguaggio. Mettere a fuoco ogni sezione, in modo che il tempo richiesto per la lettura e quello necessario per eseguire le esercitazioni siano contenuti.
- Fornire una base solida che consenta di assimilare gli argomenti in modo adeguato prima di passare a corsi più approfonditi.
Linguaggio di alto livello
La maggior parte dei linguaggi di programmazione moderni è stata progettata per essere facile da utilizzare e comprendere; per questo motivo, tali linguaggi vengono definiti linguaggi di alto livello. Java è un linguaggio di alto livello, così come la maggior parte dei linguaggi di programmazione più diffusi, come Visual Basic, C++, C#, Python o Ruby. Ma, sfortunatamente, l’hardware dei computer non è in grado di comprendere direttamente i linguaggi di alto livello. Prima che un programma scritto in un linguaggio di alto livello possa essere eseguito da un computer, questo deve essere tradotto in un altro linguaggio, comprensibile per il computer.
Il linguaggio che il computer è in grado di comprendere è chiamato linguaggio macchina. Il linguaggio assembly è una rappresentazione simbolica del linguaggio macchina, più semplice da interpretare da parte di una persona. Di conseguenza, il linguaggio assembly corrisponde in parte al linguaggio macchina, ma necessita comunque di alcune piccole trasformazioni prima di poter essere interpretato dal computer. Questi tipi di linguaggi sono definiti linguaggi di basso livello. La traduzione di un programma da un linguaggio di alto livello, come Java, a un linguaggio di basso livello viene effettuata interamente o in parte da un altro programma. Per alcuni linguaggi di alto livello, questa traduzione viene effettuata da un programma detto compilatore. Il compilatore elabora il programma scritto in linguaggi di alto livello in modo che possa essere eseguito sul computer. Questa operazione è detta compilazione del programma. Una volta compilato, è possibile eseguire il programma risultante quante volte si vuole, senza doverlo ricompilare. La terminologia usata potrebbe generare un po’ di confusione, in quanto sia l’input che l’output del compilatore sono programmi. Per evitare di confondere le idee, il programma di input per il compilatore verrà chiamato programma sorgente, detto anche codice sorgente o source code. Il programma in linguaggio macchina generato dal compilatore verrà chiamato programma oggetto o codice oggetto. La parola codice in questo caso indica l’intero programma o una sua parte.
Strumenti per la generazione di codice Java
Il compilatore
Un compilatore è un software che traduce un programma scritto in un linguaggio di alto livello (come Java), in un programma in un linguaggio più semplice che il computer è in grado di comprendere direttamente. Alcuni linguaggi di alto livello non vengono tradotti da compilatori, ma da un altro tipo di programmi, detti interpreti. Come un compilatore, un interprete traduce le istruzioni di un programma da un linguaggio di alto livello a un linguaggio di basso livello. Ma, a differenza di un compilatore, un interprete esegue ogni singola porzione di codice subito dopo averla tradotta, invece di tradurre l’intero programma in una sola passata. Utilizzare un interprete significa che mentre si esegue un programma, la traduzione si alterna all’esecuzione. Inoltre, la traduzione viene ripetuta a ogni esecuzione del programma. La compilazione viene invece svolta una volta sola e il risultante codice oggetto può essere eseguito un numero indefinito di volte, senza impiegare nuovamente il compilatore. La conseguenza è che un programma compilato viene solitamente eseguito più velocemente di un corrispondente programma interpretato.
L'interprete
Un interprete è un programma che alterna la traduzione all’esecuzione delle istruzioni di un programma scritto in un linguaggio di alto livello. Uno svantaggio dei processi appena descritti per la traduzione di programmi scritti in linguaggio di alto livello consiste nel fatto che occorre un compilatore o un interprete differente per ogni tipo di linguaggio o di computer che si sta utilizzando. Se si volesse eseguire lo stesso codice sorgente su tre diversi tipi di computer, occorrerebbe utilizzare tre diversi compilatori o interpreti. Se poi qualcuno sviluppasse un tipo di computer completamente nuovo, un gruppo di sviluppatori dovrebbe scrivere un nuovo compilatore o interprete per quel computer. Questo costituisce chiaramente un problema, poiché compilatori sono programmi di grandi dimensioni, difficili da sviluppare e quindi costosi. Al contrario di linguaggio puramente compilati, come il C, il Java utilizza un approccio leggermente diverso e più versatile, e combina compilazione e interpretazione. Tale approccio è di seguito descritto.
Bytecode Java
Il compilatore Java non traduce il programma nel linguaggio macchina specifico del computer su cui è stato compilato, ma lo traduce in un linguaggio detto bytecode. Il bytecode non è un linguaggio macchina di alcun computer. È, invece, un linguaggio macchina di una macchina virtuale (un computer virtuale) simile a tutti quelli più diffusi. Tradurre un programma scritto in bytecode nel linguaggio macchina di un computer effettivo è abbastanza semplice. Il programma che effettua questa traduzione è una specie di interprete chiamato macchina virtuale Java (Java Virtual Machine — JVM). La macchina virtuale Java ha quindi il compito di tradurre ed eseguire il bytecode Java. Per eseguire un programma Java su un computer occorre procedere come segue: in primo luogo si utilizza il compilatore per tradurre il programma sorgente Java nel bytecode corrispondente. Successivamente si utilizza la macchina virtuale Java del computer specifico per tradurre ciascuna istruzione bytecode in linguaggio macchina e per eseguire le istruzioni in linguaggio macchina.
In base a quanto descritto, sembra che il bytecode Java si limiti ad aggiungere un nuovo passo al processo. Perché, quindi, non scrivere compilatori che traducano direttamente il codice da Java al linguaggio macchina del sistema specifico. Questo può essere fatto ed è quello che viene fatto per molti altri linguaggi di programmazione. Inoltre, questo approccio permetterebbe di generare programmi oggetto molto più rapidamente. Tuttavia, il bytecode Java dona a Java un vantaggio importante; la portabilità. Dopo aver compilato il programma Java in bytecode, è possibile eseguire quel programma su qualsiasi computer dotato di una macchina virtuale Java, senza bisogno di ricompilarlo. Questo vuol dire che è possibile inviare il bytecode a un altro computer attraverso Internet e aspettarsi che questo venga eseguito, indipendentemente dal sistema operativo che viene utilizzato sul computer remoto. Questo è uno dei motivi per cui Java è particolarmente utile per lo sviluppo di applicazioni Internet.
La portabilità presenta un ulteriore vantaggio. Quando un’azienda produce un nuovo tipo di computer, gli sviluppatori Java non sono costretti a creare un nuovo compilatore. Il compilatore Java, infatti, genera bytecode che può venir eseguito su tutti i computer. Ovviamente ogni tipo di computer deve avere il proprio interprete di bytecode, la macchina virtuale Java, che traduce le istruzioni bytecode in istruzioni macchina per quel computer specifico, ma questi interpreti sono molto più semplici da sviluppare rispetto a un compilatore. Java può quindi essere aggiunto a un nuovo sistema in modo molto semplice e a un costo contenuto. Ovviamente ciascun tipo di computer impiegherà un proprio traduttore, detto interprete, che traduce le istruzioni bytecode in istruzioni nel linguaggio macchina specifico per quel computer. È importante conoscere l’esistenza del bytecode, ma nella quotidianità della programmazione non ci si accorgerà neppure della sua presenza. Normalmente si utilizzeranno due comandi: uno per compilare il programma sorgente Java nel corrispondente bytecode e l'altro per eseguire il programma. Il comando di esecuzione indica all’interprete di eseguire il bytecode; sarà tutto trasparente il fatto che il bytecode debba essere interpretato prima di essere eseguito.
Class Loader
Solo raramente un programma Java è contenuto in un unico file di codice sorgente. Al contrario, tipicamente consiste di diverse porzioni, dette classi. Si parlerà in dettaglio delle classi più avanti; per ora è sufficiente pensare alle classi come a porzioni di codice. Le classi sono spesso scritte da autori diversi e ciascuna classe viene compilata separatamente e tradotta quindi in un diverso frammento di bytecode. Per eseguire il programma, i bytecode delle diverse classi devono essere collegati fra loro. L’operazione di collegamento viene svolta da un programma detto class loader (letteralmente “caricatore delle classi”). L’operazione di collegamento è tipicamente svolta in maniera automatica. In altri linguaggi di programmazione, il...
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.