Import Statici in Java
- Java supporta l'importazione di membri statici di classi e interfacce tramite la parola chiave
import static
. - L'uso di
import static
consente di accedere ai membri statici senza dover qualificare il loro nome con il nome della classe o dell'interfaccia. - Ci sono due forme di
import static
: una per importare un singolo membro statico e l'altra per importare tutti i membri statici di una classe o interfaccia. - L'uso di
import static
può semplificare la sintassi del codice, ma è importante non abusarne per evitare conflitti di namespace. - Static import è utile quando si utilizzano frequentemente membri statici, come metodi matematici, ma si dovrebbe essere cauti nell'importare nomi statici che potrebbero causare confusione o conflitti.
import
statici
Java include una caratteristica chiamata static import
che espande le capacità della parola chiave import
.
Facendo seguire import
dalla parola chiave static
, un'istruzione import
può essere utilizzata per importare i membri statici di una classe o interfaccia. Quando si utilizza static import, è possibile riferirsi ai membri statici direttamente per nome, senza dover qualificarli con il nome della loro classe. Questo semplifica e accorcia la sintassi richiesta per utilizzare un membro statico.
Per comprendere l'utilità di static import, iniziamo con un esempio che non lo utilizza. Il seguente programma calcola l'ipotenusa di un triangolo rettangolo. Utilizza due metodi statici dalla classe matematica integrata di Java Math
, che fa parte di java.lang
. Il primo è Math.pow()
, che restituisce un valore elevato a una potenza specificata. Il secondo è Math.sqrt()
, che restituisce la radice quadrata del suo argomento.
// Calcola l'ipotenusa di un triangolo rettangolo.
class Ipotenusa {
public static void main(String[] args) {
double lato1, lato2;
double ipotenusa;
lato1 = 3.0;
lato2 = 4.0;
// Si noti come sqrt() e pow() devono essere qualificati dal
// nome della loro classe, che è Math.
ipotenusa = Math.sqrt(Math.pow(lato1, 2) +
Math.pow(lato2, 2));
System.out.println("Dati lati di lunghezza " +
lato1 + " e " + lato2 +
" l'ipotenusa è " +
ipotenusa);
}
}
Poiché pow()
e sqrt()
sono metodi statici, devono essere chiamati attraverso l'uso del nome della loro classe, Math
. Il risultato è che la sintassi diventa molto prolissa:
ipotenusa = Math.sqrt(Math.pow(lato1, 2) +
Math.pow(lato2, 2));
Come illustra questo semplice esempio, dover specificare il nome della classe ogni volta che pow()
o sqrt()
(o qualsiasi altro metodo matematico di Java, come sin()
, cos()
, e tan()
) viene utilizzato può diventare tedioso.
È possibile eliminare il tedio di specificare il nome della classe attraverso l'uso di static import, come mostrato nella seguente versione del programma precedente:
// Usa static import per portare sqrt() e pow()
// nell'ambito di visibilità del programma
import static java.lang.Math.sqrt;
import static java.lang.Math.pow;
// Calcola l'ipotenusa di un triangolo rettangolo.
class Ipotenusa {
public static void main(String[] args) {
double lato1, lato2;
double ipotenusa;
lato1 = 3.0;
lato2 = 4.0;
// Qui, sqrt() e pow() possono essere chiamati da soli,
// senza il nome della loro classe.
ipotenusa = sqrt(pow(lato1, 2) + pow(lato2, 2));
System.out.println("Dati lati di lunghezza " +
lato1 + " e " + lato2 +
" l'ipotenusa è " +
ipotenusa);
}
}
In questa versione, i nomi sqrt
e pow
sono portati nell'ambito di visibilità da queste istruzioni static import:
import static java.lang.Math.sqrt;
import static java.lang.Math.pow;
Dopo queste istruzioni, non è più necessario qualificare sqrt()
o pow()
con il nome della loro classe. Pertanto, il calcolo dell'ipotenusa può essere specificato più convenientemente, come mostrato qui:
ipotenusa = sqrt(pow(lato1, 2) + pow(lato2, 2));
Come si può vedere, questa forma è considerevolmente più leggibile.
Ci sono due forme generali dell'istruzione import static. La prima, che è utilizzata dall'esempio precedente, porta in vista un singolo nome. La sua forma generale è mostrata qui:
import static pkg.nome_tipo.nome_membro_statico;
Qui, nome_tipo
è il nome di una classe o interfaccia che contiene il membro statico desiderato. Il suo nome completo del package è specificato da pkg
. Il nome del membro è specificato da nome_membro_statico
.
La seconda forma di static import importa tutti i membri statici di una data classe o interfaccia. La sua forma generale è mostrata qui:
import static pkg.nome_tipo.*;
Se si utilizzano molti metodi statici o campi definiti da una classe, allora questa forma permette di portarli nell'ambito di visibilità senza dover specificare ciascuno individualmente. Pertanto, il programma precedente avrebbe potuto utilizzare questa singola istruzione import
per portare sia pow()
che sqrt()
(e tutti gli altri membri statici di Math
) nell'ambito di visibilità:
import static java.lang.Math.*;
Naturalmente, static import non è limitato solo alla classe Math
o solo ai metodi. Per esempio, questa riga di codice importa il campo statico System.out:
import static java.lang.System.out;
Dopo questa istruzione, è possibile fare output alla console senza dover qualificare out
con System
, come mostrato qui:
out.println("Esempio.");
In questo esempio, si può adoperare direttamente l'oggetto statico out
per stampare a schermo senza dover qualificarlo con il package System
.
Se importare System.out
come appena mostrato sia una buona idea o meno è soggetto a dibattito. Sebbene accorci l'istruzione, non è più immediatamente chiaro a chiunque legga il programma che l'out
a cui ci si riferisce è proprio System.out
.
Un altro punto: oltre a importare i membri statici di classi e interfacce definite dall'API Java, è possibile anche utilizzare static import per importare i membri statici di classi e interfacce che si creano.
Per quanto conveniente possa essere static import, è importante non abusarne. Si ricordi che la ragione per cui Java organizza le sue librerie in package è per evitare collisioni di namespace. Quando si importano membri statici, si stanno portando quei membri nel namespace corrente. Quindi, si sta aumentando il potenziale per conflitti di namespace e oscuramento accidentale di nomi. Se si utilizza un membro statico una o due volte nel programma, è meglio non importarlo. Inoltre, alcuni nomi statici, come System.out
, sono così riconoscibili che si potrebbe non volerli importare. Static import è progettato per quelle situazioni in cui si utilizza un membro statico ripetutamente, come quando si esegue una serie di calcoli matematici. In sostanza, si dovrebbe utilizzare, ma non abusare, questa caratteristica.