CodeGym /Corsi /JAVA 25 SELF /Getter e setter: sintassi, best practice

Getter e setter: sintassi, best practice

JAVA 25 SELF
Livello 15 , Lezione 2
Disponibile

1. Che cosa sono i getter e i setter

Se immagini un oggetto come una cassaforte, i suoi campi privati sono il contenuto, mentre i getter e i setter sono le chiavi dei singoli scomparti. I getter permettono di sapere che cosa c’è dentro, i setter consentono di riporre qualcosa di nuovo (ma solo se non ci metti, per esempio, un riccio al posto dei documenti).

Getter

Il getter è un metodo pubblico (public) che restituisce il valore di un campo privato (private). Di solito il suo nome inizia con get + il nome del campo con l’iniziale maiuscola.

public class Person {
    private String name; // Campo privato

    // Getter per il campo name
    public String getName() {
        return name;
    }
}

Setter

Il setter è un metodo pubblico (public) che permette di modificare il valore di un campo privato. Il suo nome inizia con set + il nome del campo con l’iniziale maiuscola.

public class Person {
    private String name;

    // Setter per il campo name
    public void setName(String name) {
        this.name = name;
    }
}

Per i campi boolean

Per i campi di tipo boolean è consuetudine usare il prefisso is nei getter:

private boolean active;

public boolean isActive() {
    return active;
}

public void setActive(boolean active) {
    this.active = active;
}

2. Sintassi e convenzioni di denominazione

Java è un linguaggio rigoroso, ma non pedante. Ci sono convenzioni consolidate che rendono il tuo codice comprensibile agli altri sviluppatori (e a te stesso tra un mese).

  • Getter: public Type getNomeCampo()
  • Setter: public void setNomeCampo(Type value)
  • Getter per boolean: public boolean isNomeCampo()

Il nome del campo nel metodo si scrive con l’iniziale maiuscola: se il campo è age, allora i metodi saranno getAge() e setAge().

Questa convenzione segue lo stile JavaBeans, grazie al quale IDE, librerie e framework possono rilevare automaticamente i tuoi getter e setter. Per esempio, se usi Spring o JavaFX, questi metodi verranno chiamati «magicamente» quando necessario.

3. Esempi di codice

Prendiamo un progettino didattico — una semplice app di «contatti» (analoga a una rubrica telefonica) — e aggiungiamo i getter e i setter fatti bene.

Esempio: classe Contact con campi privati e getter/setter

public class Contact {
    private String name;
    private String phone;
    private int age;
    private boolean favorite;

    // Getter
    public String getName() {
        return name;
    }

    public String getPhone() {
        return phone;
    }

    public int getAge() {
        return age;
    }

    public boolean isFavorite() {
        return favorite;
    }

    // Setter
    public void setName(String name) {
        this.name = name;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public void setAge(int age) {
        // Esempio di validazione: l'età non deve essere negativa
        if (age < 0) {
            System.out.println("L'età non può essere negativa!");
            return;
        }
        this.age = age;
    }

    public void setFavorite(boolean favorite) {
        this.favorite = favorite;
    }
}

Uso nell’applicazione

Contact friend = new Contact();
friend.setName("Ivan Ivanov");
friend.setPhone("+1-999-123-45-67");
friend.setAge(25);
friend.setFavorite(true);

System.out.println("Nome: " + friend.getName());
System.out.println("Telefono: " + friend.getPhone());
System.out.println("Età: " + friend.getAge());
System.out.println("Preferito: " + (friend.isFavorite() ? "Sì" : "No"));

Esempio di validazione nel setter

Nota che nel setter setAge abbiamo aggiunto un semplice controllo: se l’età è negativa, non modifichiamo il campo e mostriamo un avviso. È un modo semplice per proteggere l’oggetto da dati non corretti.

4. Best practices: come fare nel modo corretto

Non tutti i campi devono avere setter pubblici

A volte un campo deve essere di sola lettura — per esempio, un identificatore univoco impostato alla creazione dell’oggetto e mai più modificato. In tal caso il setter non si scrive proprio:

public class Contact {
    private final int id; // final — non può essere modificato dopo l'inizializzazione

    public Contact(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    // Nessun setId!
}

Usa getter/setter per controllo accessi e validazione

public void setName(String name) {
    if (name == null || name.trim().isEmpty()) {
        System.out.println("Il nome non può essere vuoto!");
        return;
    }
    this.name = name;
}

Non esporre direttamente oggetti interni mutabili

Se hai un campo — per esempio, un elenco di numeri:

private String[] phones;

Non dovresti restituirlo direttamente via getter:

public String[] getPhones() {
    return phones; // Male!
}

Un tale codice permette al codice esterno di modificare l’array a piacimento — violando l’incapsulamento!

Più corretto: restituire una copia dell’array:

public String[] getPhones() {
    return Arrays.copyOf(phones, phones.length); // Restituiamo una copia
}

Oppure semplicemente clonare:

public String[] getPhones() {
    return phones.clone(); 
}

Rendi i getter e i setter chiari e semplici

  • Non scrivere logica di business complessa in getter/setter — il loro compito è semplice: controllo degli accessi e, se necessario, validazione.
  • Se un campo non deve cambiare — non scrivere proprio il setter.
  • Se un campo non deve essere accessibile dall’esterno — non scrivere il getter.

5. Generazione automatica di getter/setter nelle IDE

Scrivere gli accessor a mano non è il massimo, soprattutto se la classe ha una decina di campi. Per fortuna, le IDE moderne (per esempio IntelliJ IDEA, Eclipse, VS Code con i plugin) sanno generarli automaticamente.

In IntelliJ IDEA

  1. Apri la classe, posiziona il cursore all’interno del corpo della classe.
  2. Premi Alt + Insert (oppure Code -> Generate...).
  3. Seleziona Getter and Setter.
  4. Spunta i campi necessari e premi OK.

Voilà! I tuoi getter e setter compariranno come per magia.

In Eclipse

  1. Apri la classe.
  2. Tasto destro — SourceGenerate Getters and Setters...
  3. Seleziona i campi e premi OK.

In VS Code (con Java Extension Pack)

  1. Apri il file della classe.
  2. Nella Command Palette (Ctrl+Shift+P) digita Generate getters and setters.
  3. Segui le istruzioni.

6. Evoluzione della tua applicazione: incapsulamento in azione

Nelle lezioni precedenti hai costruito una semplice applicazione per memorizzare contatti. Ora possiamo migliorarla rendendo i campi privati e fornendo accesso solo tramite getter/setter.

Prima (cattivo esempio):

public class Contact {
    public String name;
    public String phone;
    public int age;
}

Problema: qualsiasi codice può fare così:

Contact c = new Contact();
c.age = -1000; // Adesso abbiamo un vampiro nella rubrica!

Dopo (buon esempio):

public class Contact {
    private String name;
    private String phone;
    private int age;

    public void setAge(int age) {
        if (age < 0) {
            System.out.println("L'età non può essere negativa!");
            return;
        }
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    // Gli altri getter/setter...
}

Ora è impossibile rompere l’oggetto dall’esterno per errore (o di proposito).

7. Getter/setter per proprietà calcolate e immutabili

A volte il valore non è memorizzato in un campo, ma viene calcolato al volo:

public class Rectangle {
    private int width;
    private int height;

    public int getArea() {
        return width * height;
    }
}

Non serve un setter per l’area — non la si può impostare direttamente, si possono modificare solo larghezza o altezza.

8. Getter e setter: errori tipici

Errore n. 1: il getter/setter viola l’incapsulamento.
Se un getter restituisce un riferimento a un oggetto interno mutabile (per esempio, a una lista), il codice esterno può modificarlo aggirando tutti i controlli. Questo mina l’idea stessa di incapsulamento.

Errore n. 2: il setter non valida i dati.
Se un setter si limita ad assegnare il valore senza controllarlo, si può ottenere uno stato non valido dell’oggetto (per esempio, età negativa o nome vuoto).

Errore n. 3: generazione automatica dei setter per tutti i campi.
L’IDE può generare setter per tutti i campi, ma non è sempre corretto! Per esempio, per l’identificatore (id) il setter non serve.

Errore n. 4: logica complessa in getter/setter.
I getter e i setter devono essere semplici. Se compare logica di business complessa, è meglio estrarla in metodi separati.

Errore n. 5: violazione delle convenzioni di denominazione.
Se chiami un getter fetchName() invece di getName(), alcuni framework e librerie potrebbero non riconoscerlo.

1
Compito
JAVA 25 SELF, livello 15, lezione 2
Bloccato
Rinominare un prodotto in magazzino 🔄
Rinominare un prodotto in magazzino 🔄
1
Compito
JAVA 25 SELF, livello 15, lezione 2
Bloccato
Gestione dell'età dello studente nel database 🎓
Gestione dell'età dello studente nel database 🎓
1
Compito
JAVA 25 SELF, livello 15, lezione 2
Bloccato
Controllo della lampada intelligente: Accendi/Spegni 💡
Controllo della lampada intelligente: Accendi/Spegni 💡
1
Compito
JAVA 25 SELF, livello 15, lezione 2
Bloccato
Controllo rigoroso dell'età nel database scolastico 🏫
Controllo rigoroso dell'età nel database scolastico 🏫
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION