Java OCAJP7: variabili blank final e loro inizializzazione

Una variabile d’istanza dichiarata come final è una variabile immutabile che quindi, una volta che viene valorizzata, non può cambiare il suo valore. Le variabili d’istanza final devono essere valorizzate prima della creazione dell’istanza stessa dell’oggetto. Per questo motivo il loro valore può essere assegnato in due momenti:
1) contestualmente alla dichiarazione della variabile stessa
2) all’interno del costruttore della classe

Nell’esempio seguente, dichiariamo all’interno della nostra classe 2 variabili d’istanza, una delle quali definita come final. In questo caso valorizziamo la variabile final contestualmente alla sua dichiarazione. Non assegnamo invece un valore, né in fase di dichiarazione, né all’interno del costruttore alla variabile non etichettata come final.

public class JavaCertification  {

        private int x;
        final private int y = 10; // variabile final

        public JavaCertification() {}

        public static void main(String[] args) {
            JavaCertification jc = new JavaCertification();
            System.out.print("x = " + jc.x + " e y = " + jc.y);
    }
}

Eseguendo il programma otteniamo il seguente OUTPUT:

x = 0 e y = 10

La variabile x, che non era stata inizializzata da nessuna parte, assume il valore di default previsto dal suo tipo, che è int, e quindi 0.

Se non inizializziamo la variabile dichiarata come final contestualmente alla sua dichiarazione, otteniamo quella che viene chiamata una variabile “blank final” e, nell’esempio seguente, vediamo cosa succede in questo caso:


public class JavaCertification  {

        private int  x;
        final private int y; // blank final (variabile final non inizializzata nella dichiarazione)

        public JavaCertification() {}

        public static void main(String[] args) {
            JavaCertification jc = new JavaCertification();
            System.out.print("x= " + jc.x + " e y= " + jc.y);
    }

}

Quello che otteniamo è un ERRORE DI COMPILAZIONE

error: variable y might not have been initialized

Questo perché, come detto, una variabile final deve essere inizializzata prima dell’avvenuta creazione dell’istanza e quindi, al più tardi, nel suo costruttore.
Quindi, se una variabile final non viene inizializzata durante la sua dichiarazione (blank final), essa DEVE essere inizializzata nel suo costruttore.

Aggiungiamo quindi la valorizzazione della variabile y nel costruttore della nostra classe e proviamo ad eseguire nuovamente il programma

public class JavaCertification  {

        private int  x;
        final private int y; // blank final (variabile final non inizializzata nella dichiarazione)

        public JavaCertification() { y = 10; }  // inizializzo y nel costruttore

        public static void main(String[] args) {
            JavaCertification jc = new JavaCertification();
            System.out.print("x = " + jc.x + " e y = " + jc.y);
    }

}

Il programma esegue di nuovo correttamente ed il risultato è lo stesso ottenuto precedentemente valorizzando la variabile final contestualmente alla sua dichiarazione:

x = 0 e y = 10

A questo punto occorre fare una precisazione importante che occorre tenere ben presente per l’esame OCAJP: una variabile dichiarata come final
che non viene inizializzata contestualmente alla sua dichiarazione DEVE essere inizializzata in TUTTI i costruttori della classe.

Nell’esempio seguente dichiriamo nuovamente una variabile final e la inizializziamo solo in uno dei due costruttori previsti dalla classe:

public class JavaCertification  {
	
	private int  x;
	final private int y; // blank final (variabile final non inizializzata nella dichiarazione)
	
	public JavaCertification() { x= 0; y = 10;} // y e' inizializzata nel costruttore
	
	public JavaCertification(int pX) { this.x = pX;} // y NON inizializzata in questo costruttore
		
	public static void main(String[] args) {  
            JavaCertification jc = new JavaCertification();
            System.out.print("x= " + jc.x + " e y= " + jc.y);		
    } 

}

Eseguiamo il programma e quello che otteniamo è nuovamente un errore di compilazione, dovuto appunto al fatto che nel secondo costruttore, quello che prende un parametro intero, la variabile y dichiarata come final non viene inizializzata.

error: variable y might not have been initialized

Per risolvere il problema occorre quindi valorizzare la variabile y anche nell’altro costruttore. In questo modo, tutto compila ed esegue correttamente:

public class JavaCertification  {
	
	private int  x;
	final private int y; // blank final (variabile final non inizializzata nella dichiarazione)
	
	public JavaCertification() { x= 0; y = 10;} // y e' inizializzata nel costruttore
	
	public JavaCertification(int pX) { this.x = pX; y=10; } // y inizializzata anche qua
		
	public static void main(String[] args) {  
            JavaCertification jc = new JavaCertification();
            System.out.print("x = " + jc.x + " e y = " + jc.y);		
    } 

}

OUTPUT:

x = 0 e y = 10

Ovviamente, nel caso ci siano più costruttori che si richiamino tra di loro, occorre verificare che nella sequenza di chiamate si passi per un costruttore che valorizzi la variabile dichiarata come final.

In questo caso viene fatto:


public class JavaCertification  {

    private int  x;
    final private int y; // blank final (variabile final non inizializzata nella dichiarazione)

    public JavaCertification() { this(5,10); } // invoca l'altro costruttore

    public JavaCertification(int pX, int pY) { this.x = pX; this.y = pY; } // y valorizzata

    public static void main(String[] args) {
        JavaCertification jc = new JavaCertification();
        System.out.print("x = " + jc.x + " e y = " + jc.y);
    }
}

OUTPUT:

x = 5 e y = 10

In quest’ultimo caso invece no:

public class JavaCertification  {

    private int  x;
    final private int y; // blank final (variabile final non inizializzata nella dichiarazione)

    public JavaCertification() { this(5,10); } // richiama il costruttore di 2 parametri

    public JavaCertification(int pX, int pY) { this(pX); } // richiama il costruttore di 1 parametro
    
    public JavaCertification(int pX) { this.x = pX; } // y non valorizzata

    public static void main(String[] args) {
        JavaCertification jc = new JavaCertification();
        System.out.print("x= " + jc.x + " e y= " + jc.y);
    }
}

per cui otteniamo nuovamente l’errore:

JavaCertification.java:10: error: variable y might not have been initialized
    public JavaCertification(int pX) { this.x = pX; } 

Ancora una volta: per l’esame OCAJP7 occorre quindi prestare molta attenzione al fatto che le variabili d’istanza dichiarate come final siano valorizzate contestualmente alla loro dichiarazione oppure in TUTTI i costruttori della classe.

Leave a Reply

Your email address will not be published. Required fields are marked *