Costanti Letterali in Java

Concetti Chiave
  • Le costanti letterali in Java sono valori fissi che non cambiano durante l'esecuzione del programma.
  • Possono essere di diversi tipi, come interi, virgola mobile, booleani, caratteri e stringhe.
  • I letterali interi possono essere espressi in notazione decimale, ottale, esadecimale e binaria.
  • I letterali a virgola mobile possono essere in notazione standard o scientifica e possono essere specificati come float o double.
  • Le stringhe sono racchiuse tra virgolette doppie e possono contenere sequenze di escape per caratteri speciali.

Costanti Letterali Intere

In un programma tipico i numeri interi sono probabilmente il tipo più usato.

Qualsiasi valore numerico intero è una costante letterale intera. Esempi sono 1, 2, 3 e 42. Tutti questi sono valori decimali, cioè descrivono un numero in base 10.

Altre due basi utilizzabili nei letterali interi sono l’ottale (base otto) e l’esadecimale (base 16). In Java i valori ottali sono indicati da uno zero iniziale:

int x = 07;

I numeri decimali normali non possono avere uno zero iniziale. Pertanto un codice del genere provoca un errore:

int x = 09; // Errore di compilazione

Il valore apparentemente valido 09 genera un errore del compilatore, perché 9 è fuori dall’intervallo 0–7 dell’ottale.

Una base più comune usata dai programmatori è l’esadecimale, che si adatta bene alle dimensioni di parola modulo 8, come 8, 16, 32 e 64 bit. Un costante esadecimale si indica con uno zero seguito da x (0x o 0X). L’intervallo di una singola cifra esadecimale va da 0 a 15, quindi AF (o af) sostituiscono 10–15. Ad esempio:

int x = 0xF; // 15 in decimale
int y = 0x10; // 16 in decimale
int z = 0x1A; // 26 in decimale

Le costanti letterali intere generano un valore di tipo int, che in Java è un intero a 32 bit.

Poiché Java è fortemente tipizzato, ci si può chiedere come sia possibile assegnare un letterale intero a un altro tipo intero di Java, come byte o long, senza provocare errori di incompatibilità di tipo. Tali situazioni sono facilmente gestite: quando un valore letterale è assegnato a una variabile di tipo byte o short, non viene generato alcun errore se il valore rientra nell’intervallo del tipo destinatario.

Un letterale intero può sempre essere assegnato a una variabile di tipo long. Tuttavia, per specificare un letterale long è necessario indicarlo esplicitamente aggiungendo al valore la lettera L (maiuscola o minuscola). Per esempio, 0x7fffffffffffffffl oppure 9223372036854775807L rappresentano il long più grande. Un intero può anche essere assegnato a un char purché rientri nel relativo intervallo.

È inoltre possibile specificare letterali interi in formato binario. Per farlo si antepone al valore 0b o 0B. Ad esempio la riga seguente specifica il valore decimale 10 mediante un letterale binario:

int x = 0b1010;

Tra gli altri impieghi, l’introduzione dei letterali binari facilita l’inserimento di valori usati come maschere di bit: la rappresentazione decimale (o esadecimale) non ne evidenzia visivamente il significato, mentre il letterale binario sì.

È possibile inserire uno o più caratteri di sottolineatura (underscore) in un letterale intero per renderne più agevole la lettura. Durante la compilazione gli underscore vengono ignorati. Ad esempio, dato

int x = 123_456_789;

il valore assegnato a x sarà 123,456,789. Gli underscore saranno ignorati. Essi possono essere usati solo per separare cifre; non possono trovarsi all’inizio o alla fine di un letterale. È consentito utilizzare più di un underscore tra due cifre, come nel seguente esempio valido:

int x = 123___456___789;

L’uso degli underscore in un letterale intero è particolarmente utile per codificare valori quali numeri di telefono, identificativi cliente, codici di parte e simili. È altresì comodo per raggruppare visivamente le cifre nei letterali binari; i valori binari, per esempio, sono spesso suddivisi in gruppi di quattro cifre:

int x = 0b1101_0101_0001_1010;

Costanti Letterali in Virgola Mobile

I numeri in virgola mobile rappresentano valori decimali con una componente frazionaria.

Possono essere espressi in notazione standard o scientifica. La notazione standard consiste in una parte intera seguita da un punto decimale e da una parte frazionaria: 2.0, 3.14159 e 0.6667 sono esempi validi.

La notazione scientifica usa invece un numero in notazione standard seguito da un suffisso che indica la potenza di 10 di cui moltiplicare il numero; l’esponente è introdotto da E o e e può essere positivo o negativo, come in 6.022E23, 314159E–05 e 2e+100.

In Java i letterali a virgola mobile sono, per impostazione predefinita, di precisione double. Per indicare un letterale float occorre apporre F o f alla costante. È possibile specificare esplicitamente un letterale double con D o d, ma ciò è ridondante: il tipo double occupa 64 bit, mentre float ne richiede 32.

Sono previsti anche letterali a virgola mobile esadecimali, benché raramente usati. Essi hanno forma simile alla notazione scientifica, ma impiegano P o p al posto di E o e. Ad esempio, 0x12.2P2 è un letterale valido: il valore dopo P, detto esponente binario, indica la potenza di 2 per cui il numero viene moltiplicato; quindi 0x12.2P2 rappresenta 72,5.

Si possono inserire underscore anche nei letterali a virgola mobile, con la stessa logica vista per gli interi: servono solo a migliorarne la leggibilità e vengono rimossi in fase di compilazione. Ad esempio, dato

double numero = 9_423_497_862.0;

il valore assegnato a numero sarà 9,423,497,862.0. Gli underscore possono comparire solo tra le cifre, mai all’inizio o alla fine di un letterale. È ammesso usarne più di uno consecutivo nonché nella parte frazionaria, come mostra il seguente caso lecito:

double numero = 9_423_497.1_0_9;

In questo caso la parte frazionaria è .109.

Costanti Letterali Booleane

Le costanti letterali booleane sono semplici: esistono soltanto due valori logici, true e false.

Questi valori non si convertono in alcuna rappresentazione numerica: true non equivale a 1 né false a 0. In Java i letterali boolean possono essere assegnati solo a variabili dichiarate di tipo boolean o utilizzati in espressioni con operatori booleani.

Costanti Letterali di Carattere

In Java i caratteri sono indici nella tabella Unicode e occupano 16 bit; possono essere convertiti in interi e manipolati con gli operatori aritmetici.

Un carattere letterale viene racchiuso tra apici singoli. Tutti i caratteri ASCII visibili possono essere inseriti direttamente, ad esempio 'a', 'z' o '@'. Per quelli non digitabili direttamente esistono sequenze di escape: '\'' rappresenta l’apice singolo stesso, '\n' il carattere di newline. È inoltre possibile specificare un carattere in notazione ottale o esadecimale.

  • In notazione ottale si antepone un backslash al numero a tre cifre: '\141' è la lettera 'a'.
  • In esadecimale si usa \u seguito da quattro cifre esadecimali: '\u0061' corrisponde alla 'a' della codifica ISO Latin-1 (il byte più significativo è zero).
  • Ad esempio '\u432' rappresenta un carattere Katakana giapponese.

Stringhe Costanti

I letterali di stringa in Java sono specificati, come nella maggior parte degli altri linguaggi, racchiudendo una sequenza di caratteri tra un paio di virgolette doppie. Esempi di letterali di stringa sono

"Hello World"
"two\nlines"
"\"This is in quotes\""
Sequenza di escape Descrizione
\ddd Carattere ottale (ddd)
\uxxxx Carattere Unicode esadecimale (xxxx)
\' Apostrofo
\" Virgolette doppie
\\ Barra rovesciata
\r Ritorno carrello
\n Nuova riga (nota anche come line feed)
\f Form feed
\t Tabulazione
\b Backspace
\s Spazio (aggiunto con JDK 15)
\endofline Continua la riga (si applica solo ai blocchi di testo; aggiunto con JDK 15)
Tabella 1: Caratteri di Escape in Java

Le sequenze di escape e le notazioni ottali/esadecimali definite per i letterali di carattere funzionano allo stesso modo all’interno dei letterali di stringa.

È importante osservare che i letterali di stringa in Java devono iniziare e terminare sulla stessa riga, anche se la riga viene visualizzata a capo automatico. Per i letterali di stringa non esiste una sequenza di escape per la continuazione di riga, come avviene in alcuni altri linguaggi. (Vale la pena ricordare che, a partire da JDK 15, Java ha introdotto una funzionalità chiamata text block, che offre maggiore controllo e flessibilità quando sono necessarie più righe di testo. Vedremo più avanti in questa guida.)

Consiglio

Le stringhe sono oggetti

Come noto, in alcuni altri linguaggi le stringhe sono implementate come array di caratteri. In Java, invece, le stringhe sono effettivamente tipi oggetto. Poiché Java implementa le stringhe come oggetti, include funzionalità di gestione delle stringhe estese, potenti e semplici da usare.