Sei sulla pagina 1di 4

INTRODUZIONE A JAVA

Java è un linguaggio di programmazione moderno e potente: nato per realizzare applicazioni


embedded in apparati elettronici di vario tipo, ha riscosso molto successo nell’ambito del World Wide
Web, dove viene utilizzato per estendere le funzionalità dei browser e realizzare vere e proprie
applicazioni interattive e distribuite, che vengono chiamate applet. Un applet è una mini-applicazione,
che viene invocata all’interno di una pagina HTML: il browser trasferisce il codice dell’applet dalla
rete e lo esegue all’interno della stessa pagina, sulla macchina dell’utente. L’applet quindi esegue
autonomamente ed interagisce direttamente con l’utente mediante la propria interfaccia grafica, senza
necessità di scambiare o usare risorse del server Web da cui è stata caricata.
Java è un linguaggio di programmazione a oggetti, che adotta questa metafora estesamente: in
Java si possono solo programmare classi, costrutti programmativi quali eccezioni e thread sono forniti
attraverso classi e oggetti, la programmazione grafica avviene tramite una ricca libreria di classi di
oggetti grafici, l’interazione con l’utente avviene attraverso classi di eventi.
Java assicura la portabilità del codice attraverso una specifica precisa del linguaggio e del suo
ambiente di esecuzione. Oltre alla portabilità del sorgente, Java assicura anche la portabilità del codice
compilato, tramite la specifica della Java Virtual Machine (JVM), una macchina astratta in grado di
eseguire programmi Java. Java viene compilato in una sequenza di bytecode, che costituiscono il
linguaggio macchina della JVM. Una sequenza di bytecode può essere trasferita ed eseguita su una
qualunque sistema che realizzi la JVM, in particolare all’interno dei più comuni browser come
Netscape o Internet Explorer.
Java permette di realizzare applicazioni sicure, nei due aspetti di sicurezza locale e sicurezza di
rete.
Per quanto riguarda la sicurezza locale, Java incorpora alcune caratteristiche per evitare situazioni
anomale dovute ad errori nel programma: la gestione della memoria è svolta in maniere automatica
per evitare accessi errati alla memoria (memory leaks); tutti gli accessi agli oggetti sono soggetti ad
un controllo di tipo; ogni situazione di errore dà luogo a delle eccezioni che vengono sempre
intercettate e gestite.
Per quanto riguarda la sicurezza di rete, esistono dei meccanismi insiti nella JVM che consentono
di fare eseguire programmi importati dall’esterno con un adeguato livello di protezione per impedire
l’accidentale o intenzionale svolgimento di operazioni che danneggino il sistema o i suoi dati.
I programmi Java sono costituiti a partire da classi. Da una definizione di classe è possibile
creare diversi oggetti, dette istanze della classe. Una classe può essere considerata come uno stampo,
dal quale possono essere prodotti diversi esemplari. A differenza di uno stampo, le istanze di una
classe non sono esattamente identiche l’una all’altra: possono infatti differenziarsi per il valore dei
loro membri, variabili (detti anche attributi) o metodi. Ad esempio se una classe ha un attributo
colore, potremo avere istanze di colore rosso o di colore verde.
Gli attributi di un’istanza o di classe contengono dei valori che rappresentano le caratteristiche o
lo stato dell’oggetto o della classe. I metodi sono funzioni che operano sull’oggetto e ne manipolano
lo stato.
Ecco un esempio di come scrivere in Java un programma tradizionale:
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!"); // Stampa la frase.
}
}

Il programma consiste di una sola classe, di nome HelloWorld, che contiene un solo metodo chiamato
main. I membri della classe sono scritti tra le parentesi graffe { e } che delimitano il corpo della classe.
HelloWorld ha un unico metodo e non ha variabili. L’unico parametro del metodo main è un
vettore di oggetti di tipo String: in questo vettore si troveranno gli argomenti forniti al programma al
momento del suo avvio. Il metodo main è un metodo speciale: si tratta infatti del metodo che viene
eseguito quando si lancia una classe come applicazione a sé stante.
Nell’esempio, il metodo main contiene una sola istruzione che richiama il metodo println
dell’oggetto out della classe System. Un metodo viene richiamato utilizzando un riferimento ad un

1
oggetto e individuandolo, con l’operatore punto (.) seguito dal nome del metodo. Il metodo println
dell’oggetto out stampa una stringa seguita da un a capo.
Per poter eseguire il programma HelloWorld, occorre prima invocare il compilatore Java per
produrre il byte code eseguibile e quindi invocare l’interprete Java.

Applet

Un applet è una applicazione Java che viene invocata dall’interno di un browser o di un’altra
applicazione. Tutto quanto serve per il funzionamento di un applet è racchiuso nella classe Applet,
perciò per creare un applet è sufficiente definire una classe che eredita dalla classe Applet.
Inoltre un applet non viene lanciata direttamente perciò non ha bisogno di un metodo main(). Essa
viene lanciata all’interno di un proprio thread ed ha diverse fasi di vita in cui può passare da essere
attiva a inattiva fino a quando viene fatta terminare. Quando un applet viene lanciata all’interno di un
browser, questo le affida un’area della finestra nella quale può disegnare. Ecco una esempio di una
semplice applet che scrive una frase sullo schermo:
import java.applet.Applet;
import java.awt.Graphics;

public class HelloWorld extends Applet {


public void paint(Graphics g) {
g.drawString("Hello world!", 50, 25);
}
}

Classi

In Java l’unità fondamentale dei programmi è la classe. Le classi contengono i metodi, formati da
sequenze di codice eseguibile, sulle quali si basa la computazione. Le classi inoltre determinano la
struttura degli oggetti.
Uno dei cardini della programmazione ad oggetti è la separazione tra “che cosa” deve essere fatto
e “come” viene fatto. Il “che cosa” viene descritto dall’interfaccia pubblica di una classe, che è
costituita dai metodi (e dagli attributi) che una classe rende disponibili all’esterno. Il “come” è
costituito dal codice che implementa i metodi. Per poter usare un oggetto è sufficiente conoscere quali
metodi esso rende disponibili, senza dover conoscere come sono implementati. Questo consente di
poter cambiare l’implementazione di una classe senza che ciò si ripercuota sui programmi che la
usano.

Controllo dell’accesso e ereditarietà

Ci sono quattro forme di controllo dell’accesso ai membri di una classe:


• Public. I membri dichiarati public sono accessibili ovunque sia accessibile la classe e vengono
ereditati dalle sottoclassi
• Private. I membri dichiarati private sono accessibili esclusivamente alla classe stessa.
• Protected. I membri dichiarati protected sono accessibili ed eraditati dalle sottoclassi e
accessibili dal codice nello stesso package
• Package. I membri dichiarati senza modificatori di accesso sono accessibili esclusivamente
dal codice ed ereditati esclusivamente dalle sottoclassi nello stesso package.

Metodi

Le funzionalità di una classe sono fornite dai suoi metodi, che ne realizzano l’interfaccia. Un metodo
è una procedura con parametri che può venire invocata sugli oggetti della classe. Esso viene definito
all’interno della classe come nell’esempio precedente:
public void paint(Graphics g) {
g.drawString("Hello world!", 50, 25);
}

2
In questo caso paint è il nome del metodo, e g è il parametro di tipo Graphics. Nel corpo del metodo si
vede l’invocazione al metodo drawString dell’oggetto g, che fa uso della notazione col punto (dot
notation).
In Java è possibile che in una classe siano definiti più metodi con lo stesso nome, ma con diversa
lista di parametri. Si tratta del cosiddetto overloading, che consente di designare con un nome unico
un’operazione che può essere svolta in differenti modalità. Ad esempio, nella classe Graphics
potrebbe esistere anche un altra definizione per drawString:
void drawString(String s, Point p)

che ha solo due argomenti, di cui il secondo è un punto a due dimensioni.


Fanno parte dell’interfaccia di una classe non soltanto i metodi definiti nella classe stessa, ma
anche quelli ereditati dalle classi che la classe estende. Nel caso la classe definisca un metodo con lo
stesso nome e la stessa lista di parametri di un metodo presente in una classe da cui eredita, il nuovo
metodo maschera (override) il metodo della classe superiore.

Eccezioni

Per evitare che un programma produca effetti indesiderati, sarebbe buona norma controllare che ogni
operazione si sia conclusa senza errori, ad esempio che la lettura di un file non abbia superato il suo
limite o che un’operazione aritmetica abbia prodotto un overflow. Tuttavia l’aggiunta di questi
controlli rende il programma molto più complesso e ne rende incomprensibile il flusso logico. Spesso
chi programma in un linguaggio di programmazione tradizionale preferisce evitare di inserire questi
controlli nella presunzione che situazioni anormali non si verifichino. Questo dà origine a programmi
che a volte si piantano o producono comportamenti imprevisti.
Per evitare queste situazioni, che possono essere particolarmente fastidiose per chi sta eseguendo
un programma altrui scaricato dalla rete, Java dispone di un meccanismo di trattamento delle
eccezioni controllate.
Un metodo che rileva una situazione di errore, che non gli consente di portare a termine
normalmente l’operazione, lancia (throw) un’eccezione. L’eccezione è un oggetto di solito derivato
dalla classe Exception. Il metodo deve riportare in una clausola throws nella sua dichiarazione i tipi
di eccezione che può provocare. Un programma che invoca un metodo che produce un’eccezione deve
occuparsi di gestire tale eccezione o quanto meno dichiarare a sua volta di provocare tale eccezione. Il
compilatore Java assicura che ogni possibile eccezione generata sia trattata in qualche parte del
programma.
Il paradigma di uso delle eccezioni è la sequenza try-catch-finally. Si tenta (try) un’operazione,
se questa produce un’eccezione, la si intercetta (catch) ed infine (finally) si rimette il programma in
condizioni di proseguire.
Vediamo un esempio di uso delle eccezioni nel metodo mediaDi che calcola la media di due valori
di un array. Se un indice cade al di fuori dei limiti dell’array, viene provocata l’eccezione
MediaIllegale.
Questo nuovo tipo di eccezione viene dichiarato con la definizione:
class MediaIllegale extends Exception {}

public double mediaDi(double[] v, int i int j)


throws MediaIllegale
{
try {
return (v[i] + v[j]) / 2;
} catch(IndexOutOfBoundsException e) {
throw new MediaIllegale();
}
}

Le operazioni di accesso ad elementi di matrici in Java sono soggette al controllo sui limiti degli
indici. Qualora tale controllo non venga superato, viene generata un’eccezione di tipo
IndexOutOfBoundsException.

3
Package

Quando si scrivono programmi complessi o si mettono insieme programmi scritti da altri, aumenta il
rischio di conflitti tra i nomi delle classi o dei metodi. Il meccanismo dei package di Java consente di
risolvere questo problema: una classe viene inserita in un package ed i nomi che usa hanno validità
solo all’interno del package. I package hanno un nome e possono importati. I package contengono tipi
e sottopackage. I nomi dei package sono pertanto gerarchici, con componenti separati da un punto.
Tramite la clausola import si possono rendere accessibili da un metodo tutto o singoli elementi di
un package. In alternativa si possono indicare direttamente nomi all’interno di un package usando la
forma qualificata del nome che consiste nel nome del package seguito dal nome del componente
separato da un punto.
Ad esempio possiamo far uso della classe Date, che fa parte del package java.util, in questo modo:
java.util.Date = new Date();
Oppure iniziando il programma con:

import java.util.Date;
e scrivendo in seguito

Date = new date();