W3docs

Attributi di Classe Java (Campi)

Dichiara campi istanza in una classe Java, imposta i valori iniziali e accedi ad essi tramite gli oggetti.

Gli attributi di una classe sono le variabili dichiarate al suo interno — i dati che ogni oggetto porta con sé. La maggior parte degli autori li chiama campi (come fa la Java Language Specification), mentre "attributo" è il termine OOP più generico; significano la stessa cosa. Questo capitolo riguarda la loro dichiarazione, i valori iniziali e come leggerli e scriverli dall'esterno della classe.

Dichiarare un campo

Un campo assomiglia a una variabile locale, ma si trova nel corpo della classe anziché all'interno di un metodo:

public class Book {
  String title;
  String author;
  int    pages;
  boolean inPrint;
}

Ogni istanza di Book ottiene la propria copia di questi quattro campi. Due libri hanno due stringhe title separate, due int pages separati, e così via. Vivono per tutta la durata dell'oggetto, cioè finché nulla lo referenzia più.

Valori predefiniti

Se non inizializzi un campo, Java lo inizializza al posto tuo. I valori predefiniti dipendono dal tipo:

TipoPredefinito
byte, short, int, long0
float, double0.0
char'�' (il carattere null, code point 0 — non uno spazio)
booleanfalse
qualsiasi tipo oggettonull
Book b = new Book();
System.out.println(b.title);    // null
System.out.println(b.pages);    // 0
System.out.println(b.inPrint);  // false

Questa è una delle principali differenze tra i campi e le variabili locali nei metodi — le variabili locali non hanno un valore predefinito e il compilatore rifiuta di leggerle prima di assegnarle. I campi iniziano sempre con qualcosa.

Inizializzatori inline

Puoi assegnare un valore a un campo direttamente dove lo dichiari:

public class Book {
  String title   = "Untitled";
  int    pages   = 0;
  boolean inPrint = true;
}

L'inizializzatore viene eseguito una volta per oggetto, al momento della sua creazione. Viene eseguito in ordine di dichiarazione, prima del corpo del costruttore. Se un campo necessita di un'inizializzazione più complessa, quello è il compito del costruttore.

Leggere e scrivere i campi

Si usa <riferimento>.<campo> dall'esterno, e semplicemente <nomeCampo> (o this.<nomeCampo>) dall'interno della classe stessa:

Book b = new Book();
b.title = "Effective Java";    // write
String t = b.title;            // read

All'interno della classe:

public class Book {
  String title;
  void rename(String t) {
    title = t;             // same as this.title = t;
  }
}

Il capitolo sulla parola chiave this spiega quando è necessario il qualificatore esplicito this. e quando non lo è.

Convenzioni di nomenclatura

I nomi dei campi Java usano il lowerCamelCase:

String firstName;       // good
String first_name;      // not Java style
String FirstName;       // looks like a class

I boolean vengono spesso nominati con i prefissi is o has (isPublished, hasIndex), rendendo i punti di chiamata leggibili in modo naturale: if (book.isPublished). Le costanti — campi che non cambiano — sono scritte in UPPER_SNAKE_CASE e contrassegnate con static final, trattate nei capitoli su static e final.

Campi istanza vs campi di classe

Per impostazione predefinita, i campi appartengono a ogni istanza — ogni oggetto ha la propria copia. Aggiungendo static, il campo appartiene alla classe stessa; esiste esattamente una copia, condivisa tra tutte le istanze:

public class Counter {
  int count;            // instance — each Counter has its own
  static int total;     // class    — one shared by all Counters
}

Counter a = new Counter();
Counter b = new Counter();
a.count++;   b.count++;   b.count++;
Counter.total++;

System.out.println(a.count);          // 1
System.out.println(b.count);          // 2
System.out.println(Counter.total);    // 1, accessed through the class

Troverai la spiegazione completa nel capitolo su static; per ora, supponi che ogni campo sia un campo istanza a meno che non sia esplicitamente contrassegnato con static.

I campi pubblici sono quasi sempre un errore

Java consente di scrivere public String title; e permettere al codice esterno di accedervi e modificarlo direttamente. In pratica quasi non lo si fa mai. Una volta che un campo è pubblico, si perde la capacità di validare le scritture, cambiare il tipo in seguito o aggiungere logica alle letture — chiunque tocchi il campo è vincolato alla sua rappresentazione attuale.

Il pattern standard è contrassegnare i campi come private ed esporre invece getter e setter:

public class Book {
  private String title;

  public String getTitle()          { return title; }
  public void   setTitle(String t)  { this.title = t; }
}

Questo è l'incapsulamento. I capitoli su incapsulamento e getter e setter coprono il pattern completo. Negli esempi iniziali mostriamo i campi direttamente per chiarezza, ma il vero codice Java li mantiene privati.

I campi contengono riferimenti, non oggetti

Quando il tipo di un campo è una classe (non un tipo primitivo), il campo è un riferimento. Due oggetti possono condividere lo stesso oggetto sottostante attraverso i loro campi:

public class Author { String name; }
public class Book   { Author author; }

Author a = new Author();
a.name = "Joshua Bloch";

Book b1 = new Book();   b1.author = a;
Book b2 = new Book();   b2.author = a;     // same Author object

a.name = "J. Bloch";
System.out.println(b1.author.name);   // J. Bloch
System.out.println(b2.author.name);   // J. Bloch

Valgono gli stessi avvertimenti del capitolo precedente: a volte è ciò che si vuole, a volte è un bug. Se un Book deve avere il proprio Author, bisogna assegnare new Author() a ciascuno.

Un esempio pratico

java— editable, runs on the server

Cosa c'è dopo

I campi rappresentano lo stato di un oggetto. L'altra metà — il suo comportamento — risiede nei metodi dichiarati sulla classe. Il prossimo capitolo sui metodi di classe mostra come associare metodi alle istanze e come accedono ai campi appena definiti.

Esercitati

Pratica
Un campo istanza di tipo int è dichiarato ma non viene mai assegnato. Quale valore contiene quando lo si legge tramite un oggetto appena creato?
Un campo istanza di tipo int è dichiarato ma non viene mai assegnato. Quale valore contiene quando lo si legge tramite un oggetto appena creato?
Was this page helpful?