Paquetes en Java: qué son, para qué se utilizan, y cómo se usan (con vídeo)

14/08/2019Artículo original

Los paquetes son el mecanismo que usa Java para facilitar la modularidad del código. Un paquete puede contener una o más definiciones de interfaces y clases, distribuyéndose habitualmente como un archivo. Para utilizar los elementos de un paquete es necesario importar este en el módulo de código en curso, usando para ello la sentencia import.

La funcionalidad de una aplicación Java se implementa habitualmente en múltiples clases, entre las que suelen existir distintas relaciones. Las clases se agrupan en unidades de un nivel superior, los paquetes, que actúan como ámbitos de contención de tipos. Cada módulo de código establece, mediante la palabra clave package al inicio, a qué paquete pertenece. Como ya sabrás, con la cláusula import cualquier módulo de código puede hacer referencia a tipos definidos en otros paquetes.

Vamos a familiarizarnos con los procedimientos para construir paquetes, para referenciarlos desde otros puntos y también veremos la relación existente entre paquetes, clases y el sistema de archivos donde se almacena el proyecto.

Creación de paquetes

Un paquete Java se genera sencillamente incluyendo la palabra clave package al inicio de los módulos de código en los que se definen las clases que formarán parte del mismo. Trabajando en un proyecto con NetBeans, comprobaremos que en la ventana Projects los paquetes se representan con un icono específico y actúan como nodos contenedores, alojando los módulos .java con el código fuente. El menú contextual del proyecto nos ofrece la opción New>Java Package, que será el que usemos habitualmente para crear un nuevo paquete:

Un paquete puede contener, además de definiciones de tipos como las clases e interfaces, otros paquetes, dando lugar a estructuras jerárquicas de contenedores. La denominación de los subpaquetes, paquetes contenidos en otros, se compondrán del identificador del contenedor seguido de un punto y el nombre del subpaquete. De existir niveles adicionales se agregarían los distintos identificadores separados por puntos, formando así el nombre completo del paquete.

  Pyston 2.2 es un Python que promete ser un 30% más rápido: sus creadores quieren que sustituya al lenguaje de programación

El diagrama siguiente representa el contenido de un paquete llamado campusmvp, teóricamente correspondiente a un proyecto de aplicación de contabilidad. En ese paquete de primer nivel tenemos un subpaquete con utilidades, llamado campusmvp.util, no directamente vinculadas con la aplicación de contabilidad. El subpaquete campusmvp.conta contendría todos los elementos asociados a dicha aplicación, distribuidos a su vez en un tercer nivel de paquetes que contienen las clases correspondientes al modelo, la vista, etc., siguiendo al patrón arquitectónico MVC. Cada uno de los módulos de definición de clase, denominados Cuenta.java, Movimiento.java, Vista.java, etc., comenzarían con una cláusula package indicando el nombre completo del paquete al que pertenecen:

Importación de paquetes

Los paquetes Java son como cajas de herramientas, cada una de ellas con una colección distinta de instrumentos útiles para nuestro trabajo, a las que podemos necesitar acceder cada vez que abordamos el desarrollo de un nuevo proyecto. Es en este contexto donde recurriremos a la cláusula import, a fin de importar en el ámbito actual las definiciones de otro paquete y poder usarlas según el procedimiento habitual, creando objetos, accediendo a los servicios de las clases, etc.

La cláusula import puede utilizarse para importar un elemento concreto de un paquete, facilitando el nombre de este seguido de un punto y el identificador de dicho elemento. Por ejemplo, para importar la clase Math del paquete java.lang, pudiendo así acceder a la constante PI y las funciones matemáticas que aporta, bastaría con la siguiente línea:

import java.lang.Math;

Es habitual que al importar un paquete nos interesen muchas de las clases definidas en el mismo. En este caso podríamos importarlas individualmente, usando la sintaxis anterior, o bien podríamos recurrir a la siguiente alternativa. Esto nos permitiría usar la clase Math, así como la clase System, la clase Thread y muchas otras definidas en el paquete java.lang:

import java.lang.*;

En ocasiones, como ocurre con la clase Math, importamos una clase para acceder directamente a sus miembros estáticos, constantes y métodos, no para crear objetos a partir de ellas, lo que nos fuerza a utilizar constantemente la sintaxis Clase.miembro, por ejemplo Math.PI o Math.sin(). Si tras importar la clase Math intentamos referirnos a estos miembros simplemente por su nombre, como se hace en la mitad superior de la siguiente imagen, obtendremos un error. En estos casos podemos recurrir a la sintaxis import static paquete.clase.*, cuya finalidad es incluir en el ámbito actual los miembros estáticos de la clase indicada. Es lo que se hace en la mitad inferior de la siguiente imagen:

  Python sobrepasa a Java como lenguaje de programación más popular por primera vez en los 20 años del indice TIOBE

Relación entre clases, paquetes y el sistema de archivos

En Java existe una estrecha relación entre las definiciones de paquetes y clases y el sistema de archivos local, en el que se almacenan los módulos conteniendo el código. Es un hecho que puede pasarnos totalmente inadvertido al trabajar con un IDE como el de NetBeans, ya que sus opciones se encargan de ocultar estos detalles. No obstante, es interesante que conozcamos dicha relación ya que esto nos permitirá, en caso de necesidad, trabajar directamente con el JDK.

Cada módulo de código de un proyecto Java únicamente puede contener una clase pública, cuyo nombre, respetando mayúsculas y minúsculas, debe coincidir con el del módulo. Es decir, existe una correspondencia directa entre los identificadores de clase y archivos en los que se alojan. Esto no afecta a las clases anidadas y otras clases no públicas que pudiesen definirse en el mismo módulo.

  31 cursos online gratuitos que puedes comenzar en junio para aprender una nueva habilidad este verano sin tener que pagar nada

El nombre del paquete establece además el nombre de la carpeta donde se alojan los módulos de código contenidos en el paquete. Los nombres de paquete pueden ser compuestos, usándose el punto como separador de las diferentes porciones del identificador. Cada parte identificaría a un subdirectorio, según se muestra en el siguiente esquema:

Al trabajar desde la línea de comandos, usando directamente el JDK, hemos de tener en cuenta que tanto la compilación como la ejecución verificarán que se satisface la correspondencia entre el nombre de paquete y clase y la estructura de directorios y nombre de archivo. Si esta no se cumple en algún punto, como ocurre en la parte inferior de la siguiente imagen, se obtiene un error.

A continuación puedes ver un vídeo práctico explicativo de todo lo anterior, que está extraído directamente del curso de programación con Java de campusMVP:

[youtube:x4BDc-VGeZY]
Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Contiene enlaces a sitios web de terceros con políticas de privacidad ajenas que podrás aceptar o no cuando accedas a ellos. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad