Viaggio al centro del Java

Di questi tempi del Java si parla ovunque come di un'invenzione rivoluzionaria e indispensabile per ogni applicazione moderna, non solo per i browser.
La SUN, nel White Paper, presenta il Java come un linguaggio di programmazione Object Oriented semplice e familiare a chi conosce il C++, indipendente dall'architettura, e sicuro per l'uso in rete. In effetti, lo stesso programma funziona su PC, MAC, SGI, UNIX senza richiedere modifiche o ricompilazioni, e non si conoscono virus Java o hacking maliziosi.
Però, per chi non conosce il C++, Java risulta difficile da imparare come qualsiasi altro linguaggio, sia esso un Basic o lo stesso C++, e per essere multipiattaforma è usata la tecnica del bytecode: la compilazione non crea eseguibili .EXE specifici per un particolare sistema operativo, ma dei .class che devono essere interpretati dalla JVM (Java Virtual Machine) implementata sui vari sistemi. Ciò rende l'esecuzione molto più lenta di un programma normale, e solo con gli ultimi JIT (Just in Time compiler) di Nestcape 3 ed Explorer 3 si ha un'esecuzione accettabile. Comunque, dato che la velocità dei processori attuali è alta, e la conversione per differenti piattaforme di programmi C++ richiede tempo e denaro, il bytecode si è rivelato vincente.
Altra caratteristica è il multithreading, ossia la possibilità di eseguire più "flussi di esecuzione" contemporanei, caratteristica già implementata in modo non standard anche nei C++ per sistemi multitasking: la rivoluzione sta nell'evitare di impararsi miriadi di librerie e funzioni di 3 o 4 sistemi operativi per rendere disponibile il proprio programma su PC, MAC e UNIX vari.
I programmi che si eseguono dal browser, "attaccati" alle pagine HTML, sono detti applet, mentre quelli eseguibili solo con l'interprete java da shell DOS sono detti applications; è possibile creare anche programmi eseguibili sia come applet che come application.
Se si visitano delle pagine web contenenti applet, ad esempio www.gamelan.com o www.jars.com, ci si possono trovare programmi di ogni tipo (disegno, simulazione, editing, database), esattamente come quelli che usiamo quotidianamente, ma in più è possibile accedere a dati remoti o inviarli, "uscendo" dal nostro Hard Disk per scambiare dati con computer diversi, senza bisogno di conversioni difficili o impossibili.
Molte cose si possono già fare con i programmi CGI, ma Java offre interfacce utente migliori e risparmia lavoro al server, delegando molte delle operazioni al client che, a differenza dei normali FORM, può anche elaborare dati.
Occorre infine precisare che il Javascript ha poco a che fare con il Java, in quanto Javascript è solo uno scripting language (tipo i batch) creato da Netscape: va scritto nell'HTML, e viene interpretato. Il Javascript è disponibile anche sui sistemi a 16 bit, come Windows 3.11, a differenza del Java.


Panoramica sul linguaggio

Nel Java troviamo i costrutti WHILE, FOR, IF-ELSE, le variabili INT (intere) e FLOAT (a virgola mobile), gli array, detti anche vettori, ed una sintassi simile al C: spesso si possono riutilizzare algoritmi C senza modifiche. I blocchi di istruzioni sono delimitati dalle parentesi graffe {...} come in C e in PERL.
Consiglio a chi dispone di materiale didattico sul C di utilizzarlo come base, escludendo puntatori, unioni e #define, che non sono implementati, e sorvolando anche la gestione delle stringhe di testo; infatti in Java le le stringhe sono oggetti, e non array di char, e gli array stessi sono oggetti. Questo dimostra che Java e' più Object Oriented del C++. Comunque inizieremo programmando alla vecchia maniera, per evitare traumi.


Installazione di Java e suo uso

Come prima cosa occorre ottenere il JDK (Java Developer Kit) specifico per il vostro sistema, scaricandolo dal sito ftp://ftp.javasoft.com.
La versione per win95 e' JDK-1_0_2-win32-x86.exe e si trova in /pub. Eseguendo questo file, si formano varie sottodirectory: il compilatore è in \BIN. Per poterlo usare, la directory \BIN va messa nel path, aggiungendo questa linea in fondo all'AUTOEXEC.BAT:

SET PATH=%PATH%;C:\JAVA\BIN;

Naturalmente il \BIN nel vostro caso può trovarsi altrove, sostituite quindi C:\JAVA\BIN col percorso che avete, ad esempio D:\JDK\JAVA\BIN. Dopo un reboot, scrivete nello shell (prompt del DOS):

javac

Se viene caricato, ottenendo la lista dei suoi parametri, il path funziona e siamo già pronti per programmare, basta scrivere i listati con un editor di testi come l'edit del DOS o il blocco note di win95


Il nostro primo programma

Inizieremo con delle applicazioni, lasciando le applet ai prossimi articoli. Dobbiamo iniziare dichiarando una classe entro la quale racchiudere il programma. Stabiliamo che la classe si chiami Appli1, quindi dovremo chiamare il listato Appli1.java, per evitare errori di compilazione. Fate molta attenzione al fatto che il Java e' case sensitive (ossia fa differenza tra lettere maiuscole e minuscole), per cui Appli1 è diverso da aPpLi1 o appli1.
All'interno della classe dichiareremo i metodi (in altri linguaggi sono chiamati funzioni, subroutines o sottoprogrammi): le applicazioni devono avere almeno il metodo main(). Ecco lo scheletro di una applicazione:

class Appli1 { // Inizio della classe
public static void main(String args[]) {
// Qua scriveremo il programma
} // Fine del metodo main()
} // Fine della classe

Si può notare l'uso delle parentesi graffe annidate per aprire e chiudere i blocchi, e i commenti (ignorati dal compilatore) che iniziano dopo i //.
Per ora tralasciamo ciò che precede il main, e vediamo le variabili, che devono essere sempre dichiarate prima dell'uso:

int pippo; // Variabile intera
float pluto; // Variabile float
pippo=3; // pippo ora vale 3
pluto=1.5; // pluto ora vale 1,5

Per dichiarare una variabile si scrive il nome che vogliamo dargli preceduto dal tipo, senza dimenticarci di terminare ogni linea con un punto e virgola.
Il nome delle variabili non può iniziare con un numero, né può contenere simboli come &,/,!, e le maiuscole sono considerate diverse dalle maiuscole, per cui Pippo è diverso da pippo e PIPPO. Per cambiare valore alla variabile si usa l'operatore di assegnamento "=".
Dobbiamo rendere visibili i risultati del programma:

System.out.print("Ciao mondo");
System.out.print(pippo);
System.out.println(pippo);

Si tratta di un metodo che stampa a video testi o valori di variabili: nel primo caso stampiamo un testo, racchiuso tra apici, nel secondo il valore della variabile pippo, che nel nostro caso è 3.
Il terzo caso si usa println, che fa andare anche a capo dopo la stampa: prima si e' scritto "Ciao mondo3", tutto sulla stessa linea, dopo il println invece si va anche a capo.
Per fare un programma degno di chiamarsi tale, ci vorrebbe almeno un loop, cioè l'esecuzione di alcune istruzioni ripetuta per un numero stabilito di volte. Ad esempio, per scrivere 100 volte "Ciao mondo" sullo schermo, si possono mettere 100 istruzioni print di seguito, oppure un loop che esegue 100 volte lo stesso print. L'istruzione FOR è perfetta per fare questo tipo di cicli:

int pippo; // Variabile intera

// Usiamo pippo come contatore per
// un loop for, incrementandolo da 0 a
// 99 per un totale di 100 cicli.

for(pippo=0; pippo<100; pippo++) {
System.out.print("Ciao mondo!");
} // Fine del FOR

Le istruzioni che si trovano nel blocco del for, delimitato dalle parentesi graffe, saranno eseguite finche' pippo è minore di 100, e dato che lo inizializiamo a 0, da 0 a 99 ci sono 100 passaggi. Il pippo++ significa "incrementa pippo di 1".
La struttura del FOR quindi è questa: all'interno delle parentesi tonde ci sono 3 campi separati da punti e virgola. Nel primo si assegna alla variabile, usata come contatore, il valore iniziale; nel secondo campo c'è la condizione per continuare il loop o fermarsi, che e' un'espressione del tipo "variabile minore di x", "variabile uguale ad x", eccetera. Gli operatori relazionali che si possono usare sono: > e < per maggiore e minore, == per "uguale" e != per "diverso", infine >= e <= per "maggiore o uguale" e "minore o uguale". Il loop prosegue finché la condizione è vera, e si ferma quando diviene falsa.
Nel terzo campo modifichiamo la variabile contatore, altrimenti non si raggiunge mai la condizione per terminare il loop (il programma rimarrebbe bloccato).
Nel nostro caso incrementiamo di 1, e per farlo si puo' scrivere pippo=pippo+1, ma esiste l'abbreviazione pippo++, analoga a pippo-- che invece decrementa di 1.
Con il loop for modifichiamo il normale flusso lineare di esecuzione del programma, dove le istruzioni sono eseguite una dopo l'altra, in sequenza, finchè non si arriva "in fondo".
Quando l'esecuzione è al for, esegue le istruzioni nel suo blocco {...}, controlla la condizione, incrementa il contatore, e se la condizione è sempre vera "torna indietro" a rieseguire le istruzioni nel blocco. Questo processo è simile a un vecchio disco musicale che si inceppa suonando lo stesso pezzo ripetutamente.
E' possibile anche saltare l'esecuzione di certe istruzioni, a seconda che sia verificata o meno una condizione, tramite l'IF:

if(pippo==5) {
System.out.println("Tombola!");
}

Questo significa: se pippo = 5, stampa "Tombola!". La condizione da mettere tra parentesi è analoga a quella del FOR. Con questo otteniamo il listato 1, con un loop FOR che esegue 10 volte un blocco di istruzioni, tra le quali c'è un IF che esegue il suo sotto-blocco solo quando la variabile pippo, usata come contatore, vale 5.


Compiliamo ed eseguiamo il listato

Se avete scritto correttamente il listato 1 e lo avete salvato come Appli1.java, dovreste poterlo compilare da shell DOS con:

javac Appli1.java

Ricordatevi che la A iniziale è maiuscola e il resto minuscolo.
Se non appaiono messaggi, la compilazione è andata a buon fine, verificate quindi che sia stato creato il file Appli1.class, eseguendolo con:

java Appli1

Da notare che non si deve scrivere il suffisso .class. L'output dovrebbe essere la stampa dieci volte del valore di pippo, sempre crescente, con il "Tombola!" soltanto quando vale 5.
Nota per chi ha l'Apple Mac: per compilare si deve portare l'icona del sorgente .java sull'icona del compilatore, e per eseguire il .class si fa un doppio click sulla sua icona.


Leggiamo l'input dell'utente

Il programma precedente non è interattivo, in quanto non elabora dati immessi dall'utente: agisce senza vedere il mondo esterno. Il primo sistema che viene in mente è quello di leggere eventuali argomenti (parametri) passati nella linea comandi, ossia scritti dopo il nome del programma, analogamente al "/p" che si mette dopo il DIR per attivare l'opzione di paginazione.
Avrete notato uno "String args[]" nel main(): si tratta degli eventuali argomenti passati all'applicazione, sotto forma di array di stringhe.
Le stringhe in Java sono oggetti di tipo String. Gli array sono una specie di "collezione" di elementi, tutti raggruppati sotto lo stesso nome (in questo caso args), a cui si può accedere singolarmente specificandone l'indice, ad esempio:

args[0] Prima stringa
args[1] Seconda stringa

L'indice parte da zero e arriva fino al numero di elementi contenuti-1.
Vediamo di fare un programma che somma 2 numeri: innanzitutto dobbiamo controllare se l'utente ha immesso i 2 parametri. Per sapere quanti elementi ha l'array args si usa il suo metodo length():

if(args.length < 2) {
System.out.println("Scrivi 2 numeri!");
return; // Esci
}

Se args non ha almeno 2 elementi, provochiamo l'uscita dal programma, dopo il messaggio di avvertimento.
Superato questo controllo, dato che i due numeri li abbiamo come stringhe, dobbiamo convertirli in variabili int o float, nel nostro caso usiamo le variabili num1 e num2 di tipo float:

num1 = Float.valueOf(args[0]).floatValue();
num2 = Float.valueOf(args[1]).floatValue();

Per convertire in int si usa Int.valueOf().intValue(), come avrete già intuito. Ora basta sommare e stampare il risultato:

num3=num1+num2; // Sommiamo
System.out.print("La somma di " + num1);
System.out.print(" e " + num2 + " e': ");
System.out.println(num3);

Abbiamo introdotto l'operatore "+", che assume due funzioni diverse: nel primo caso è in una assegnazione, quindi addiziona num1 e num2, ponendo il risultato in num3. Invece nel print serve ad attaccare pezzi di testo (tra virgolette) e variabili, per comporre frasi miste.
Verifichiamolo compilando ed eseguendo il listato 2, passandogli 2 numeri nella linea comandi:

javac Appli2.java ; Compilazione
java Appli2 10.5 3 ; Esecuzione

Come risultato otteniamo:

La somma di 10.5 e 3 e': 13.5

Un altro modo di ottenere input è quello di leggere una stringa durante l'esecuzione, usando il metodo readLine() di un oggetto DataInputStream il cui "flusso" attinga dal System.in, cioé dove l'utente scrive con la tastiera. Prima dichiariamo l'oggetto, chiamandolo "leggimi", poi lo istanziamo (cioè ne creiamo una copia) con l'operatore NEW:

DataInputStream leggimi;
leggimi = new DataInputStream(System.in);

L'unica complicazione deriva dal fatto che per usare il metodo readLine() occorre prevedere cosa fare in caso di errori (eccezioni), tramite l'uso di try, nel quale si prova ad eseguire l'istruzione, e catch, che "coglie" l'eventuale l'eccezione per eseguire le istruzioni di emergenza:

try {
mionome = leggimi.readLine();
}
catch (Exception e) {
System.out.println("Errore!");
return; // Esci
}

Se l'istruzione nel try genera eccezione, viene eseguito il blocco di istruzioni del catch.
L'ultima cosa da fare è importare il package I/O che permette di usare il DataInputStream, scrivendo all'inizio del listato:

import java.io.*;

Il listato 3 chiede all'utente di scrivere il suo nome, e come risposta lo saluta. Il programma non è certo l'ultimo grido in fatto di intelligenza artificiale, ma illustra bene le ultime cose spiegate.

Fabio Ciucci
fabioc@anfiteatro.it


Scarica il listato 1: Appli1.java

Scarica il listato 2: Appli2.java

Scarica il listato 3: Appli3.java


Torna all' indice degli articoli