back to top

Java: i modificatori final e static

Abbiamo fino a questo momento parlato degli aspetti principali della programmazione ad oggetti in Java. Prima di analizzare l’ultima parte di questo argomento, cioรจ le interfacce, รจ bene capire l’effetto che i modificatori final e static hanno nei vari contesti in cui sono utilizzati.

Il modificatore final

Il modificatore final รจ semplice da comprendere, poichรฉ le implementazioni possibili sono legate alla sua traduzione letterale: finale o non mutabile. La sua funzione principale รจ quella di limitare la modificabilitร  delle variabili, dei metodi e delle classi.

Pubblicitร 

Dunque, il modificatore final puรฒ essere utilizzato per definire una variabile che diverrร  una costante per l’istanza della classe. รˆ importante notare che final puรฒ essere applicato anche ai metodi di una determinata classe. Un metodo definito come final implica che, se ereditiamo la classe che contiene il metodo, non sarร  possibile eseguire l’override. Inoltre, se una classe รจ dichiarata come final, impediamo la sua estensione. Questo รจ logicamente comprensibile, poichรฉ una classe dichiarata con il modificatore final รจ concepita per essere completa e non necessita di specializzazioni o estensioni.

Il modificatore static

Il modificatore static รจ un concetto piรน complesso, ma estremamente potente. Iniziamo con il dire che il modificatore static puรฒ essere applicato sia a metodi che a variabili di una classe. L’effetto di dichiarare un metodo static รจ quello di rendere il metodo comune a tutte le istanze della classe.

Per capire meglio il concetto, pensiamo a tutte le funzioni matematiche che Java ci mette a disposizione attraverso la classe Math. Ad esempio, la classe Math offre il metodo max, che restituisce il massimo tra due interi. Possiamo utilizzarlo con il seguente codice:

Math.max(3, 4);

La chiamata del metodo รจ diversa da quanto visto finora: non abbiamo istanziato la classe Math, nรฉ abbiamo richiamato il metodo max utilizzando la sintassi nomeOggetto.nomeMetodo(). Questo รจ possibile perchรฉ possiamo richiamare il metodo statico con la sintassi nomeClasse.nomeMetodo(). L’uso di static consente di evitare di istanziare la classe, preservando l’invariabilitร  dei suoi metodi. Per esempio, il valore massimo tra 3 e 4 sarร  sempre 4; nulla potrร  modificare tale relazione. รˆ consigliabile utilizzare il modificatore static con parsimonia e solo se applicabile al concetto di uniformitร  delle funzionalitร .

Esaminiamo ora cosa succede quando utilizziamo il modificatore static su una variabile di istanza. In questo caso, l’attributo della classe diventa comune a tutte le istanze. Consideriamo un esempio pratico con una semplice classe Prova contenente un solo attributo statico:

public class Prova {
  public static int numero;
}

La classe di implementazione per il nostro esempio sarร :

public class Implementazione {
  public static void main(String[] args) {
    Prova prova1 = new Prova();
    Prova prova2 = new Prova();
    prova1.numero = 10;
    System.out.println("Il valore numero per l'istanza 1 รจ: " + prova1.numero);
    System.out.println("Il valore numero per l'istanza 2 รจ: " + prova2.numero);
  }
}

L’output dell’esecuzione della classe Implementazione sarร :

Il valore numero per l'istanza 1 รจ: 10
Il valore numero per l'istanza 2 รจ: 10;

In sintesi, se dichiariamo una variabile di istanza utilizzando il costrutto public static, otteniamo una variabile globale accessibile da tutte le istanze di una classe. Sebbene le variabili globali offrano il vantaggio di condividere lo stesso valore tra tutte le istanze, comportano anche dei rischi. Qualora un’istanza modifichi la variabile globale, tutte le altre istanze della classe vedranno il valore aggiornato, ciรฒ compromette la robustezza e l’integritร  dell’intera applicazione.

Pubblicitร