Nel linguaggio Java, come in tanti altri linguaggi di programmazione, esistono una serie di parole “speciali” che sono riservate ed hanno un significato particolare per il linguaggio. Questo articolo serve per fornire un breve riassunto di tutte queste parole speciali in Java, in modo che possa risultare una utile guida di riferimento, soprattutto per chi sta studiando (o ripassando) il linguaggio Java.
Parole chiave
Le “parole chiave” (keywords) sono delle parole speciali che hanno un significato particolare all’interno del linguaggio e sono utilizzate come istruzioni, dichiarazioni, clausole e altri costrutti specifici del linguaggio. La regola basilare delle parole chiave è che non possono essere usate come “identificatori”, cioè una parola chiave non può essere usata esattamente come nome di variabile, metodo, classe e altro elemento a cui si può dare un nome.
Ad esempio:
String break = "fine"; // ERRORE! break è una parola chiave
abstract
è un “modificatore” che si utilizza per dichiarare che una classe o un metodo è “astratto”:
- una classe astratta non è istanziabile direttamente (indipendentemente da quali/quanti costruttori possiede) e il suo scopo principale è di essere estesa da un’altra classe per poter fare qualcosa di più concreto
- un metodo astratto non ha un “corpo” e deve poi essere implementato in una classe concreta (non
abstract
)
assert
è la istruzione che si utilizza per definire una “asserzione” secondo il meccanismo delle “asserzioni” (solo da Java 1.4). La istruzione assert
può avere due forme:
assert
espressione-booleana;
assert
espressione-booleana:
espressione-dettaglio;
Nota: prima di Java 1.4 la parola assert
si poteva usare come “identificatore”.
boolean
è il tipo primitivo booleano che può avere solo i valori true
(“vero”) e false
(“falso”).
break
è l’istruzione che si utilizza per terminare immediatamente un ciclo con/senza label (“etichetta”) oppure un blocco di codice con label.
byte
è il tipo primitivo numerico a 8 bit (con segno) che può avere valori da -27 (-128) a 27-1 (127) entrambi inclusi.
case
è la clausola che si utilizza all’interno della istruzione switch
per eseguire del codice specifico quando il valore dichiarato dal case
corrisponde a quello nella espressione di switch
.
catch
è la clausola che può opzionalmente seguire la istruzione try
per catturare una eccezione che avviene all’interno del blocco di codice del try
.
char
è il tipo primitivo numerico a 16 bit (senza segno) per trattare caratteri nell’intervallo dei codici Unicode da '\u0000'
a '\uffff'
, con valori numerici da 0 a 216-1 (65535) entrambi inclusi.
class
è la parola che si utilizza per definire una classe Java.
const
è una parola riservata del linguaggio ma non ha alcun utilizzo pratico.
continue
è la istruzione che si utilizza per far saltare immediatamente alla successiva iterazione di un ciclo for
/ while
/ do
-while
con o senza label (“etichetta”).
default
è una parola che si utilizza in tre contesti differenti:
- per definire il “caso” di default all’interno della istruzione
switch
- per dichiarare il valore di default di un elemento nella definizione di una annotation (solo da Java 5)
- per definire un metodo di default in una interfaccia (solo da Java 8)
do
è la istruzione che inizia il ciclo do-while, in cui il blocco di codice viene eseguito almeno una volta di prima di testare l’espressione booleana specificata alla fine nella clausola while
.
double
è il tipo primitivo numerico che rappresenta valori in floating-point a 64 bit.
else
è la clausola opzionale che si utilizza insieme alla istruzione if
per eseguire del codice alternativo quando la condizione del if
è false
(“falsa”).
enum
è la parola che si utilizza per definire un tipo “enumerativo” di cui ci possono essere solo un numero fisso e predeterminato di valori (solo da Java 5). Nota: prima di Java 5 la parola enum
si poteva usare come “identificatore”.
extends
è la parola che si utilizza nella dichiarazione di una classe o di una interfaccia nei seguenti modi:
- nella dichiarazione di una classe per specificare che estende una (e solo una) altra classe
- nella dichiarazione di una interfaccia per specificare che estende una o più altre interfacce
final
è un “modificatore” che si utilizza in tre contesti differenti:
- nella dichiarazione di una classe per specificare che non può essere estesa
- nella dichiarazione di un metodo per specificare che non può essere ridefinito (override) in una sotto-classe
- nella dichiarazione di una variabile per specificare che il suo valore non può cambiare dopo che la variabile è stata inizializzata (ovvero diventa una “costante”)
finally
è la clausola che può opzionalmente seguire la istruzione try
per specificare il blocco di codice che deve essere sempre eseguito in ogni caso.
float
è il tipo primitivo numerico che rappresenta valori in floating-point a 32 bit.
for
è la istruzione di ciclo che ha due forme possibili, quella “base” e il enhanced-for:
- forma “base”: con inizializzazione/condizione/incremento, similare al for dei linguaggi C/C++
for (
inizializzazione;
condizione;
incremento)
istruzione-o-blocco - forma enhanced-for (solo da Java 5): per iterare più facilmente su array e in generale su oggetti che implementano la interfaccia
java.lang.Iterable
for (
Tipo:
oggetto-iterabile)
istruzione-o-blocco
goto
è una parola riservata del linguaggio ma non ha alcun utilizzo pratico.
if
è la istruzione che permette di eseguire del codice in maniera “condizionata”, solo quando la espressione booleana nella condizione del if
è true
(“vera”).
implements
è la parola che si utilizza solo nella dichiarazione di una classe per specificare che implementa una o più interfacce.
import
è la parola che si utilizza all’inizio del sorgente (dopo la eventuale dichiarazione di package e prima delle definizioni delle classi) per effettuare una dichiarazione di import di un tipo o di un membro static
. Esistono quattro forme di import:
- single-type-import per importare un singolo tipo, es.:
import nome.package.Tipo;
- type-import-on-demand per importare tutti i tipi di un package, es.:
import nome.package.*;
- single-static-import per importare un membro
static
di un tipo (solo da Java 5), es.:
import static nome.package.Tipo.nomeMembro;
- static-import-on-demand per importare tutti i membri
static
di un tipo (solo da Java 5), es.:
import static nome.package.Tipo.*;
instanceof
è l’operatore che si utilizza nella forma oggetto instanceof
TipoX per verificare se un oggetto passa il test IS-A (“è-un”) rispetto ad un tipo X specificato a destra di instanceof
, ovvero se l’oggetto è esattamente di tipo X oppure un sotto-tipo di X.
int
è il tipo primitivo numerico a 32 bit (con segno) che può avere valori da -231 (-2147483648) a 231-1 (2147483647) entrambi inclusi.
interface
è una parola che si utilizza in due contesti differenti:
- come
interface
per definire una interfaccia Java - come
@interface
per definire una annotation Java (solo da Java 5)
long
è il tipo primitivo numerico a 64 bit (con segno) che può avere valori da -263 (-9223372036854775808) a 263-1 (9223372036854775807) entrambi inclusi.
native
è un “modificatore” che si utilizza solo nella dichiarazione di un metodo per specificare che la sua implementazione è fatta con del codice “nativo” della piattaforma.
new
è l’operatore che si utilizza per creare una istanza di una classe oppure di un array.
package
è la parola si utilizza come prima dichiarazione in un sorgente Java per specificare il package a cui appartengono tutti i tipi definiti nel sorgente.
private
è un “modificatore di accesso” che si utilizza nella dichiarazione di un costruttore o un membro (variabile, metodo o inner/nested class) di una classe per specificare che deve essere visibile solo all’interno di quella classe.
protected
è un “modificatore di accesso” che si utilizza nella dichiarazione di un costruttore o un membro (variabile, metodo o inner/nested class) di una classe per specificare che deve essere visibile:
- direttamente a qualunque altra classe nello stesso package
- alle sotto-classi (solo per ereditarietà!) in altri package
public
è un “modificatore di accesso” che si utilizza:
- nella dichiarazione di un tipo top-level (classe, interfaccia, enum, annotation) per specificare che deve essere visibile a qualunque altra classe in qualunque package
- nella dichiarazione di un costruttore o un membro (variabile, metodo o inner/nested class) di una classe per specificare che deve essere visibile a qualunque altra classe in qualunque package
return
è una istruzione che si utilizza in tre contesti differenti:
- per terminare un costruttore (senza poter specificare un valore di ritorno)
- per terminare un metodo, con/senza valore di ritorno
- per terminare il blocco di una lambda expression, con/senza valore di ritorno (solo da Java 8)
short
è il tipo primitivo numerico a 16 bit (con segno) che può avere valori da -215 (-32768) a 215-1 (32767) entrambi inclusi.
static
è un “modificatore” che si applica su un membro (variabile o metodo) di una classe per specificare che il membro appartiene alla classe e non a ciascun distinto oggetto di quella classe. Quando static
è applicato ad una classe “innestata”, la fa diventare una nested class, che è ben differente rispetto ad una inner class.
strictfp
è un “modificatore” (solo da Java 1.2) che si applica ad un tipo (classe, interfaccia, enum) oppure ad un metodo per specificare che in tutta la classe o in un singolo metodo le espressioni di tipo float
/double
devono essere trattate rigorosamente secondo lo standard IEEE-754, garantendo quindi gli stessi risultati su piattaforme differenti. Nota: prima di Java 1.2 la parola strictfp
si poteva usare come “identificatore”.
super
è una parola che si utilizza in tre contesti differenti:
- come prima istruzione di un costruttore per invocare un costruttore della super-classe utilizzando la forma
super(
……);
(con/senza argomenti) - per invocare un metodo di una super-classe utilizzando la forma
super.metodo()
- per accedere ad un campo di una super-classe utilizzando la forma
super.campo
switch
è la istruzione che si utilizza per eseguire più “casi” di codice differenti in base al valore di una espressione che può essere di tipo:
char
(oppurejava.lang.Character
tramite auto-unboxing solo da Java 5)byte
(oppurejava.lang.Byte
tramite auto-unboxing solo da Java 5)short
(oppurejava.lang.Short
tramite auto-unboxing solo da Java 5)int
(oppurejava.lang.Integer
tramite auto-unboxing solo da Java 5)- enum (solo da Java 5)
String
(solo da Java 7)
synchronized
si utilizza per far acquisire al thread “corrente” il monitor (lock) intrinseco di un oggetto nei seguenti modi:
- come “modificatore” nella dichiarazione di un metodo “di istanza” (non
static
) per acquisire il monitor dell’oggetto su cui il metodo è stato invocato, rilasciando poi il monitor alla terminazione del metodo - come “modificatore” nella dichiarazione di un metodo “di classe” (
static
) per acquisire il monitor dell’oggettojava.lang.Class
associato alla classe, rilasciando poi il monitor alla terminazione del metodo - come istruzione nella forma
synchronized (
oggetto)
istruzione-o-blocco per acquisire il monitor di un oggetto specifico, rilasciando poi il monitor alla terminazione della istruzione o blocco.
this
è la parola che serve per fare riferimento all’oggetto “corrente”:
- in un metodo “di istanza” (non
static
),this
è il riferimento all’oggetto su cui il metodo è stato invocato - in un costruttore,
this
è il riferimento all’oggetto in fase di costruzione
throw
è la istruzione che si utilizza per lanciare una eccezione.
throws
è la clausola che si utilizza nella dichiarazione di un metodo per elencare i tipi di eccezione (tipicamente “checked”) che il metodo dichiara di essere in grado di lanciare.
transient
si utilizza solo su una variabile “di istanza” (non static
) di una classe per specificare che la variabile deve essere completamente ignorata dal meccanismo della serializzazione degli oggetti di Java.
try
è la istruzione che si utilizza per eseguire un blocco di codice in cui le eccezioni vengono tenute sotto “controllo” per poter essere catturate da una eventuale clausola catch
che segue il blocco try
.
void
si utilizza principalmente solo nella dichiarazione di un metodo per dichiarare che non restituisce alcun valore. Nel contesto della reflection di Java, void
può essere trattato in modo particolare come “pseudo” tipo per ottenere il riferimento all’oggetto java.lang.Class
relativo a void
utilizzando l’espressione void.class
.
volatile
è un “modificatore” che si applica solo alle variabili “di istanza” (non static
) e “di classe” (static
) per garantire la “visibilità” delle modifiche tra thread differenti, in modo da assicurare che un thread B legga sempre l’ultimo valore impostato precedentemente da un thread A.
while
è la istruzione che inizia il ciclo while, in cui il blocco di codice viene (ri)eseguito solo dopo aver testato l’espressione booleana specificata nella condizione del while
.
_
(underscore) viene considerato come parola riservata per usi “futuri” a partire da Java 9 ma ad oggi non ha (ancora) alcun utilizzo pratico.
Valori letterali
I “valori letterali” (literal values o semplicemente literal) in generale sono delle espressioni che rappresentano un valore all’interno del sorgente. Le parole elencate di seguito non sono esattamente delle parole chiave, nel senso che non rientrano nell’elenco fatto nella sezione precedente, ma sono comunque parole riservate del linguaggio e per tale motivo, allo stesso modo, non possono essere usate come “identificatori”.
false
è il valore letterale del tipo boolean
che rappresenta la condizione di “falso”.
null
è il valore letterale dei tipi reference che denota l’assenza di un riferimento ad un oggetto.
true
è il valore letterale del tipo boolean
che rappresenta la condizione di “vero”.
Altre parole particolari
Esistono da tempo delle parole particolari in Java che non sono strettamente “parole chiave” e nemmeno “valori letterali”. Sono invece degli “identificatori limitati” (restricted identifiers), cioè hanno un significato particolare per il linguaggio solo in alcuni contesti molto ristretti mentre in qualunque altro contesto si possono utilizzare come “identificatori”.
record
è una parola che ha un significato speciale a partire da Java 14 nel contesto della dichiarazione del nuovo tipo di classe Record. Si veda l’articolo Breve introduzione ai Record di Java 14
var
è una parola che ha un significato speciale a partire da Java 10 solo nel contesto della dichiarazione di una variabile locale per dichiarare la variabile senza dover specificare il tipo (in pratica viene applicato un meccanismo di “inferenza” del tipo in base al valore assegnato). Si veda l’articolo Variabili locali con “var” da Java 10
yield
è una parola che ha un significato speciale a partire da Java 14 solo all’interno della istruzione switch
, quando è usata come espressione, per produrre un valore da utilizzare come risultato dello switch
.