Importare Package in Java

Concetti Chiave
  • Per utilizzare classi di package differenti, in Java esistono due modi.
  • Il primo è utilizzare il nome completamente qualificato della classe, che include il nome del package.
  • Il secondo è importare il package o la classe specifica utilizzando l'istruzione import.
  • import può essere adoperato sia per importare un intero package che per importare classi specifiche.

Importazione dei Package

Poiché i package sono un buon meccanismo per compartimentalizzare classi diverse tra loro, è facile capire perché tutte le classi Java integrate siano memorizzate nei package.

Non ci sono classi core di Java nel package predefinito senza nome; tutte le classi standard sono memorizzate in qualche package con nome.

Poiché le classi all'interno dei package devono essere completamente qualificate con il loro nome di package o i loro nomi, potrebbe diventare noioso digitare ogni volta il lungo nome del percorso del package separato da punti per ogni classe che si desidera utilizzare.

Per questa ragione, Java include l'istruzione import per rendere visibili certe classi, o interi package. Una volta importata, una classe può essere riferita direttamente, utilizzando solo il suo nome. L'istruzione import è una comodità per il programmatore e tecnicamente non è necessaria per scrivere un programma Java completo. Tuttavia, se si fa riferimento a una dozzina di classi nella propria applicazione, l'istruzione import farà risparmiare molto tempo nella digitazione.

In un file sorgente Java, le istruzioni import appaiono immediatamente dopo l'istruzione package (se esiste) e prima di qualsiasi definizione di classe. Questa è la forma generale dell'istruzione import:

import pkg1[.pkg2].(classname | *);

Qui, pkg1 è il nome di un package di primo livello, e pkg2 è il nome di un package subordinato all'interno del package esterno, separato da un punto (.).

Non c'è alcun limite pratico alla profondità della gerarchia del package, eccetto quello imposto dal file system. Infine, si specifica esplicitamente un classname o un asterisco (*), che indica che il compilatore Java dovrebbe importare l'intero package. Questo frammento di codice mostra entrambe le forme in uso:

import java.util.Date;
import java.io.*;

Tutte le classi standard di Java SE incluse con Java iniziano con il nome java. Le funzioni di base del linguaggio sono memorizzate in un package chiamato java.lang. Normalmente, è necessario importare ogni package o classe che si desidera usare, ma poiché Java è inutile senza buona parte della funzionalità in java.lang, essa è implicitamente importata dal compilatore per tutti i programmi. Questo equivale alla seguente riga inserita in cima a tutti i programmi:

import java.lang.*;
Nota

Conflitto di nomi di classe

Se una classe con lo stesso nome esiste in due package differenti che vengono importati usando la forma con asterisco, il compilatore non emetterà nessun errore, a meno che non si provi a utilizzare una delle due classi. In quel caso, si riceverà un errore in fase di compilazione e sarà necessario specificare esplicitamente la classe indicando il suo package.

Va sottolineato che l'istruzione import è opzionale. In qualsiasi punto in cui si usa il nome di una classe, è possibile utilizzare il suo nome completamente qualificato, che include l'intera gerarchia del package. Per esempio, questo frammento usa un'istruzione import:

import java.util.*;
class MiaData extends Date {
}

Lo stesso esempio senza l'istruzione import appare così:

class MiaData extends java.util.Date {
}

In questa versione, Date è completamente qualificato.

Controllo degli Accessi nei Package

Riportiamo qui la tabella che abbiamo già visto nella lezione sui package e il controllo degli accessi:

Categoria private Nessun Modificatore protected public
Stessa classe
Sottoclasse stesso package No
Non-sottoclasse stesso package No
Sottoclasse altro package No No
Non-sottoclasse altro package No No No
Tabella 1: Accesso ai Membri di Classe

Come mostrato nella Tabella, quando un package è importato, solo gli elementi all'interno del package dichiarati come public saranno disponibili per classi che non sono sottoclassi nel codice che importa. Per esempio, se si desidera che la classe Saldo del package miopacchetto mostrata in precedenza sia disponibile come classe autonoma per l'uso generale al di fuori di miopacchetto, sarà necessario dichiararla come public e inserirla in un proprio file, come mostrato di seguito:

package miopacchetto;

/* Ora, la classe Saldo, il suo costruttore e il metodo
   mostra() sono pubblici. Questo significa che possono
   essere usati da codice non-sottoclasse al di fuori del loro package.
*/
public class Saldo {
    String nome;
    double bil;

    public Saldo(String n, double b) {
        nome = n;
        bil = b;
    }

    public void mostra() {
        if(bil < 0)
            System.out.print("--> ");
        System.out.println(nome + ": $" + bil);
    }
}

Come si può vedere, la classe Saldo è ora public. Anche il suo costruttore e il metodo mostra() sono public. Questo significa che possono essere accessibili da qualsiasi tipo di codice al di fuori del package miopacchetto. Per esempio, qui ProvaSaldo importa miopacchetto ed è quindi in grado di usare la classe Saldo:

import miopacchetto.*;

class ProvaSaldo {
    public static void main(String[] args) {
        /* Poiché Saldo è public, si può usare la classe
           e chiamare il suo costruttore. */
        Saldo prova = new Saldo("J. J. Jaspers", 99.88);

        prova.mostra(); // si può anche chiamare mostra()
    }
}
Consiglio

Accesso negato senza public

Come esperimento, rimuovere lo specificatore public dalla classe Saldo e poi provare a compilare ProvaSaldo. Come spiegato, si verificheranno degli errori.