CodeGym /Corsi /JAVA 25 SELF /Inizializzazione di un oggetto: ordine di inizializzazion...

Inizializzazione di un oggetto: ordine di inizializzazione

JAVA 25 SELF
Livello 14, Lezione 5
Disponibile

1. Ordine di inizializzazione di un oggetto in Java: chi per primo, chi per ultimo?

Creare un oggetto in Java non è semplicemente «allocare memoria e scriverci dei valori». È un vero e proprio rituale con un ordine preciso di azioni. Se immaginiamo il processo di inizializzazione come il lancio di un razzo, ogni stadio ha il suo posto ben definito.

Quando scrivi:

Person vasya = new Person("Vasya", 30);

Java esegue i seguenti passaggi:

  1. Alloca memoria per l’oggetto e assegna a tutti i campi i valori predefiniti.
  2. Esegue le inizializzazioni esplicite dei campi (se hai indicato i valori direttamente in fase di dichiarazione).
  3. Esegue tutti i blocchi di inizializzazione non statici (ordinari) — nell’ordine in cui sono scritti nella classe.
  4. Esegue il corpo del costruttore che hai invocato tramite new.

Vediamo ogni passaggio nel dettaglio.

2. Inizializzazione dei campi

Valori predefiniti

Quando l’oggetto viene appena creato (ancora prima di assegnare qualcosa esplicitamente), tutti i suoi campi ricevono i valori predefiniti:

Tipo di campo Valore predefinito
int, short, byte, long
0
float, double
0.0
boolean
false
char
'\u0000' (carattere nullo)
Tipi di riferimento (String, altri oggetti)
null

Inizializzazione esplicita

Se al momento della dichiarazione del campo assegni subito un valore, quel valore verrà impostato dopo i valori predefiniti, ma prima dell’esecuzione del costruttore.

public class Person {
    private String name = "Senza nome";
    private int age = 18;
}

Se crei l’oggetto con un costruttore vuoto, questi valori rimarranno. Se lo crei con un costruttore con parametri — con ogni probabilità verranno sovrascritti.

3. Blocchi di inizializzazione: a cosa servono e come funzionano

In Java è possibile dichiarare i cosiddetti blocchi di inizializzazione non statici (ordinari). Vengono eseguiti ogni volta che si crea un oggetto, subito dopo l’inizializzazione dei campi, ma prima del costruttore.

Sintassi:

public class Person {
    {
        System.out.println("Si esegue il blocco di inizializzazione non statico!");
    }
}

Se in una classe ci sono più blocchi di questo tipo, vengono eseguiti nell’ordine in cui sono scritti.

Esempio con più blocchi

public class Person {
    private String name = "Senza nome";

    {
        System.out.println("Blocco 1: name = " + name);
        name = "Enigma";
    }

    {
        System.out.println("Blocco 2: name = " + name);
    }

    public Person() {
        System.out.println("Costruttore: name = " + name);
    }
}

Se creiamo un oggetto:

Person p = new Person();

L’output sarà:

Blocco 1: name = Senza nome
Blocco 2: name = Enigma
Costruttore: name = Enigma

A cosa servono i blocchi di inizializzazione?

Nella pratica, i blocchi di inizializzazione si usano raramente. Di solito tutto ciò che puoi fare in un blocco lo puoi fare o nella dichiarazione del campo, o nel costruttore. Ma talvolta (per esempio, se hai più costruttori e una parte della logica di inizializzazione deve essere comune a tutti) i blocchi di inizializzazione possono essere comodi.

4. Costruttore: l’ultimo tocco dell’inizializzazione

Dopo che tutti i campi hanno ricevuto i valori (predefiniti o espliciti) e sono stati eseguiti tutti i blocchi di inizializzazione, viene chiamato il costruttore — proprio quello che hai indicato dopo new.

Nel costruttore in genere imposti i valori finali dei campi, accetti i parametri ed esegui altra inizializzazione che dipende dai dati in ingresso.

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        System.out.println("Costruttore: name = " + name + ", age = " + age);
        this.name = name;
        this.age = age;
    }
}

5. Dimostrazione dell’ordine completo di inizializzazione

Scriviamo una classe che mostri esplicitamente in quale ordine avviene l’inizializzazione.

public class Person {
    private String name = "Senza nome";
    private int age = 18;

    {
        System.out.println("Blocco di inizializzazione: name = " + name + ", age = " + age);
        age = 21;
    }

    public Person() {
        System.out.println("Costruttore senza parametri: name = " + name + ", age = " + age);
    }

    public Person(String name, int age) {
        System.out.println("Costruttore con parametri: name = " + name + ", age = " + age);
        this.name = name;
        this.age = age;
    }

    public void printInfo() {
        System.out.println("Person: name = " + name + ", age = " + age);
    }
}

E ora nella nostra classe principale (per esempio, Main):

public class Main {
    public static void main(String[] args) {
        System.out.println("Creiamo l'oggetto p1:");
        Person p1 = new Person();
        p1.printInfo();

        System.out.println("\nCreiamo l'oggetto p2:");
        Person p2 = new Person("Petya", 30);
        p2.printInfo();
    }
}

L’output sarà all’incirca questo:

Creiamo l'oggetto p1:
Blocco di inizializzazione: name = Senza nome, age = 18
Costruttore senza parametri: name = Senza nome, age = 21
Person: name = Senza nome, age = 21

Creiamo l'oggetto p2:
Blocco di inizializzazione: name = Senza nome, age = 18
Costruttore con parametri: name = Senza nome, age = 21
Person: name = Petya, age = 30

Nota bene: nel costruttore con parametri i valori dei campi sono ancora quelli vecchi (quelli dopo il blocco di inizializzazione), mentre solo dopo il costruttore i campi ricevono i valori finali.

6. Diagramma dell’ordine di inizializzazione

Ecco un piccolo schema (flowchart) per visualizzare il processo:

flowchart TD
    A[Allocazione della memoria, valori predefiniti] --> B[Inizializzazione esplicita dei campi]
    B --> C[Esecuzione dei blocchi di inizializzazione non statici]
    C --> D[Esecuzione del costruttore]
    D --> E[Oggetto pronto all’uso]

7. Particolarità e sfumature

Campi statici e blocchi statici

In questa lezione parliamo solo di campi e blocchi non statici. I campi e i blocchi statici vengono inizializzati una sola volta al caricamento della classe, e non a ogni creazione dell’oggetto. Ne parleremo più in dettaglio negli argomenti dedicati all’incapsulamento.

Quando viene inizializzato che cosa?

  • Campi — a ogni creazione dell’oggetto.
  • Blocchi di inizializzazione — a ogni creazione dell’oggetto.
  • Campi e blocchi statici — una sola volta al caricamento della classe.

Si può accedere ai campi nei blocchi di inizializzazione?

Sì, è possibile! Ma è importante ricordare che, se un campo è dichiarato sotto il blocco, esiste già; se però vi accedi prima dell’inizializzazione esplicita, otterrai il valore predefinito.

8. Errori tipici nell’inizializzazione degli oggetti

Errore n. 1: aspettarsi che i campi siano inizializzati prima della loro dichiarazione.
In Java l’ordine di dichiarazione dei campi e dei blocchi di inizializzazione nella classe ha importanza. Se in un blocco di inizializzazione accedi a un campo dichiarato più in basso, esso esiste già ma non è ancora inizializzato esplicitamente — avrà il valore predefinito.

Errore n. 2: duplicare l’inizializzazione nei blocchi e nei costruttori.
I principianti spesso ripetono la stessa logica sia nel blocco sia nel costruttore. Meglio usare o il blocco o il costruttore, oppure richiamare un costruttore da un altro tramite this(...).

Errore n. 3: aspettarsi che i campi statici vengano inizializzati a ogni creazione dell’oggetto.
I campi e i blocchi statici funzionano diversamente — vengono inizializzati una sola volta al caricamento della classe.

Errore n. 4: utilizzare campi di riferimento non inizializzati.
Se ti dimentichi di inizializzare esplicitamente un campo di riferimento (per esempio, String name;), allora sarà uguale a null finché non gli assegni un valore esplicitamente in un blocco di inizializzazione o nel costruttore.

1
Compito
JAVA 25 SELF, livello 14, lezione 5
Bloccato
Osservazione della comparsa di creature virtuali
Osservazione della comparsa di creature virtuali
1
Compito
JAVA 25 SELF, livello 14, lezione 5
Bloccato
Standardizzazione dei nuovi libri nella casa editrice
Standardizzazione dei nuovi libri nella casa editrice
1
Compito
JAVA 25 SELF, livello 14, lezione 5
Bloccato
Monitoraggio dell'inizio dell'assemblaggio di ogni auto in fabbrica
Monitoraggio dell'inizio dell'assemblaggio di ogni auto in fabbrica
1
Compito
JAVA 25 SELF, livello 14, lezione 5
Bloccato
Il percorso dello studente verso il voto finale
Il percorso dello studente verso il voto finale
1
Sondaggio/quiz
Classi e costruttori, livello 14, lezione 5
Non disponibile
Classi e costruttori
Classi e costruttori
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION