
Los paquetes es la forma que tiene Java de organizar los archivos con las clases necesarias para construir las aplicaciones. Java incorpora varios paquetes, por ejemplo java.lang, java.io, o java.util con las clases básicas para construir programas: System, String, Integer, Scanner . . .
Sentencia package
¿Cómo se puede definir un paquete?, la sentencia package se utiliza para este cometido. En primer lugar se debe incluir la sentencia package como primera línea del archivo fuente de cada una de las clases del paquete. Por ejemplo, si las clases Lapiz, Boligrafo y Folio se van a organizar formando el paquete escritorio, el esquema a seguir es el siguiente:
// archivo fuente Lapiz.java
package escritorio;
public class Lapiz{
// miembros de clase Lapiz
}
// archivo fuente Boligrafo.java
package escritorio;
public class Boligrafo{
// miembros de clase Boligrafo
}
// archivo fuente Folio.java
package escritorio;
public class Folio{
// miembros de clase Folio
}
Formato
package NombrePaquete;
En segundo lugar, una vez creado el archivo fuente de cada clase del paquete, se deben ubicar estos en un subdirectorio con el mismo nombre que el del paquete. En el esquema anterior se ubicarán los archivos Lapiz.java, Boligrafo.java, y Folio.java en el path escritorio. El uso de paquetes tiene dos beneficios importantes:
- Las restricciones de visibilidad son menores entre clases que están dentro del mismo paquete. Desde cualquier clase de un paquete, los miembros protected y los miembros sin modificador de visibilidad son accesibles; sin embargo no lo son desde clases de otros paquetes.
- La selección de las clases de un paquete se puede abreviar con la sentencia import del paquete.
import
Las clases que se encuentran en los paquetes se identifican utilizando el nombre del paquete, el selector punto (.) y a continuación el nombre de la clase. Por ejemplo, la declaración de la clase Arte con atributos de la clase PrintStream (paquete java.io) y Lapiz (paquete escritorio):
Ejemplo
public class Arte{
private java.io.PrintStream salida;
private escritorio.Lapiz p;
}
La sentencia import facilita la selección de una clase, permite escribir únicamente su nombre, evitando el nombre del paquete. La declaración anterior se puede abreviar:
import java.io.PrintStream;
import escritorio.*;
public class Arte{
private PrintStream salida;
private Lapiz p;
}
La sentencia import debe aparecer antes de la declaración de las clases, a continuación de la sentencia package. Tiene dos formatos:
Formato
import identificadorpaquete.nombreClase;
import identificadorpaquete.*;
El primer formato especifica una clase concreta. El segundo formato especifica que para todas las clases del paquete no hace falta cualificar el nombre de la clase con el nombre del paquete.
Con frecuencia se utiliza el formato .* . Tiene la ventaja de poder simplificar cualquier clase del paquete, se pueden señalar los siguientes problemas:
- Se desconoce qué clases concretas del paquete se están utilizando. Por contra, con una sentencia import por cada clase se conocen las clases utilizadas.
- Puede haber colisiones entre nombres de clases declaradas en el archivo y nombres de clases del paquete.
- Mayor tiempo de compilación debido a que el compilador busca la existencia de cualquier clase en el paquete.
Nota
Aunque aparezca la sentencia import paquete.*, el compilador genera bytecode solo para las clases utilizadas.
Ejemplo
Se crea el paquete numérico con la clase Random y se utiliza la clase en una aplicación.
package numerico;
public class Random{
// . . .
}
Al utilizar la clase en otro archivo:
import java.util.*;
import numerico.*;
En el paquete java.util se encuentra la clase Random, entonces se produce una ambigüedad con la clase Random del paquete numérico. Es necesario cualificar completamente el nombre de la clase Random de, por ejemplo, java.util.
java.util.Random aleatorio; // define una referencia