Al momento stai visualizzando Underscore in Java

Underscore in Java

Questo articolo fa parte della serie “Stranger things in Java”, dedicata agli approfondimenti del linguaggio che ci permetteranno di padroneggiare anche gli scenari più strani che si possono presentare quando programmiamo. Tutti gli articoli sono ispirati dal contenuto dal libro “Java for Aliens” (in inglese) e dal libro “Il nuovo Java”.

In questo articolo cercheremo di fare chiarezza sull’utilizzo del simbolo di sottolineatura_” (in inglese underscore) nella programmazione Java. Esaminiamo quindi i casi d’uso di questo simbolo all’interno di un programma Java. Partiamo dal caso più noto.

 

Underscore ed identificatori

Sappiamo che è possibile utilizzare il simbolo di underscore come parte di un identificatore (nome) di un elemento di programmazione. Infatti per definire un identificatore in Java, possiamo usare

  • Lettere maiuscole e minuscole
  • Numeri (ma non all’inizio dell’identificatore)
  • Il simbolo di dollaro ‘$’ (che però non viene praticamente mai utilizzato)
  • Il simbolo di underscore ‘_

Tuttavia, in generale le convenzioni standard per la definizione dei nomi delle variabili, dei metodi, dei tipi Java (classi, interfacce, enumerazioni, record e annotazioni), dei package e dei moduli, non richiedono l’uso del simbolo underscore. Nella programmazione Java, solo la convenzione standard per gli identificatori delle costanti richiede l’utilizzo del simbolo di underscore. Infatti, tale convenzione consiglia di definire nomi costituiti da soli caratteri maiuscoli, e di utilizzare il simbolo underscore come separatore di parole per migliorare la leggibilità. Per esempio:

final int NUMERO_LATI_DI_UN_QUADRATO = 4;
final double PI_GRECO = 3.14;

Questo perché una costante deve essere facilmente riconoscibile, ed utilizzando tutti i caratteri maiuscoli lo sviluppatore riesce a distinguere le costanti dalle variabili a colpo d’occhio.

 

Novità in Java 8

Sino alla versione 8 di Java era possibile utilizzare addirittura il solo simbolo underscore come identificatore di un elemento di programmazione Java, come una variabile o un metodo. Nella versione 8 però, il compilatore già suggeriva allo sviluppatore con un warning di non usare questa pratica. Infatti, se provavamo a definire per esempio una variabile in questo modo con Java 8:

int _;

il codice veniva compilato correttamente, ma veniva stampato questo warning:

warning: '_' used as an identifier
        int _;
            ^
(use of '_' as an identifier might not be supported in releases after Java SE 8)
1 warning

che ci avvertiva che l’utilizzo del simbolo di underscore come identificatore potrebbe non essere più supportato nelle versioni future.

 

Novità in Java 9

Infatti, se proviamo a compilare il codice precedente con una versione successiva alla 8, otterremo direttamente il seguente errore in compilazione:

error: as of release 9, '_' is a keyword, and may not be used as an identifier
        int _;
            ^
1 error

che ci avverte che già dalla versione 9 non è più possibile utilizzare un singolo underscore come identificatore.

Notare che nel messaggio del compilatore l’underscore viene definito come keyword (parola chiave), il che non è del tutto corretto. Una keyword in Java ha un significato ben preciso, come per esempio class, while oppure instanceof. Sarebbe più opportuno definire l’underscore come una reserved word (parola riservata), ovvero una parola che non ha un particolare significato per la sintassi Java, ma che non può essere utilizzata come identificatore di un metodo. Le altre parole riservate definite dal linguaggio sono goto e const, che in effetti non hanno nessun significato per la sintassi Java, ma non sono accettate dal compilatore come identificatori.

Tuttavia, è possibile utilizzare due o più underscore consecutivi come identificatore senza problemi. Infatti la seguente dichiarazione viene compilata senza errori:

int __;

 

Underscore per tipi numerici interi

Dalla versione 7 di Java, per migliorare la leggibilità dei valori assegnati alle nostre variabili numeriche, è possibile usare anche gli underscore. Per esempio, la seguente dichiarazione:

int i = 1000000000;

può essere riportata come segue:

int i = 1_000_000_000;

rendendo manifesto che il valore della variabile i rappresenta la cifra di un miliardo.

L’underscore si può utilizzare anche per migliorare la leggibilità di tipi numerici scritti con altre notazioni. Per esempio, la seguente dichiarazione che si avvale della notazione binaria contraddistinta dal prefisso 0b (oppure 0B):

int bytes = 0b10100001010001011010000101000101;

può essere riscritta separando i vari byte con underscore:

int bytes = 0b10100001_01000101_10100001_01000101;

È evidente che l’uso dell’underscore garantisce una maggiore leggibilità dei nostri valori numerici.

 

Altre notazioni per tipi numerici interi

Possiamo anche rappresentare un numero intero in formato esadecimale contraddistinto dal prefisso 0x (oppure 0X):

long maxLong = 0x7fff_ffff_ffff_ffffL;

O anche un numero intero in formato ottale, per esempio separando il prefisso 0 che caratterizza questa notazione dal numero ottale, che spesso confonde le idee allo sviluppatore. Infatti

int ottale = 052;

in realtà è un numero ottale che convertito come numero decimale vale 42! Riscrivendolo così:

int ottale = 0_52;

avremo meno probabilità di confonderci.

Possiamo in teoria utilizzare sequenze di più underscore adiacenti:

int ottale = 0__________52;

 

Underscore per tipi numerici floating point

Anche per i tipi numerici a virgola mobile float e double possiamo usare il simbolo di underscore, per esempio:

final float PI_GRECO = 3.14_15F;

oppure:

double d = 0.000_000_001;

È anche possibile utilizzare la notazione esponenziale o ingegneristica contraddistinta dall’uso della lettera ‘e’ (che può essere sia maiuscola sia minuscola), per esempio:

double d = 0.260_174E-2; //equivalente a 0.260174 diviso 100 = 0.00260174

 

Un’unica regola da ricordare

C’è un’unica regola da rispettare per poter utilizzare correttamente gli underscore con i tipi di dati numerici:

  • È possibile utilizzare uno o più underscore solo tra due numeri

Per esempio le seguenti dichiarazioni non sono valide:

final float PI_1 = 3_.1415F;
final double PI_2 = 3._1415D;
long socialSecurityNumber  = 999_99_9999_L;
int x1 = _52;
int x2 = 52_;
int x3 = 0_x52;
int x4 = 0x_52;
int x5 = 0x52_;

Notare che la dichiarazione ottale che abbiamo visto prima:

int ottale = 0_52;

è valida in quanto il prefisso non contiene un carattere, ma solo lo 0, che è una delle cifre utilizzabili per un numero ottale (che ricordiamo può utilizzare solo 8 cifre: 0, 1, 2, 3, 4, 5, 6 e 7).

Per la stessa ragione la seguente dichiarazione è valida:

long maxLong = 0x7fff_ffff_ffff_ffffL;

In questo caso infatti, f non è da intendersi come un carattere, ma in realtà è una delle possibili cifre di un numero esadecimale (che ricordiamo può utilizzare 16 cifre: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f). Nella notazione esadecimale f vale 15.

 

Conclusioni

In questo articolo abbiamo esplorato i casi d’uso in cui possiamo utilizzare l’underscore nella programmazione Java. In particolare abbiamo visto che, oltre alla convenzione che ne richiede l’utilizzo nella dichiarazione degli identificatori delle costanti, da Java 7 in poi è possibile utilizzare l’underscore come separatore di cifre (sia intere che decimali), per renderle più semplici da interpretare. Questa pratica è tanto più utile quando più i valori da definire sono alti, ed è semplice da utilizzare visto che c’è un’unica regola da rispettare. Inoltre abbiamo visto anche che da Java 9 in poi non possiamo più usare un singolo underscore come identificatore di un elemento di programmazione Java.

 

Note dell’autore

Questo articolo è basto su alcuni paragrafi del capitolo 3 del mio libro “Il nuovo Java” e del mio libro in inglese “Java for Aliens”.

Lascia un commento