Java paquete (package)

Para organizar mejor las clases, Java proporciona el mecanismo de paquetes, que se utiliza para diferenciar los espacios de nombres de los nombres de clase.

Función del paquete

  • 1. Organizar las clases o interfaces con funciones similares o relacionadas en el mismo paquete, para facilitar la búsqueda y el uso de las clases.

  • 2. Al igual que las carpetas, los paquetes también utilizan un método de almacenamiento de directorios en árbol. Los nombres de las clases en el mismo paquete son diferentes; los nombres de las clases en diferentes paquetes pueden ser iguales. Cuando se invocan simultáneamente dos clases con el mismo nombre de clase en diferentes paquetes, se debe agregar el nombre del paquete para distinguirlas. Por lo tanto, los paquetes pueden evitar conflictos de nombres.

  • 3. El paquete también limita los permisos de acceso; solo las clases con permiso de acceso al paquete pueden acceder a las clases de un paquete determinado.

Java utiliza el mecanismo de paquete (package) para prevenir conflictos de nombres, control de acceso, y proporcionar búsqueda y localización de clases (class), interfaces, enumeraciones (enumerations) y anotaciones (annotation), etc.

El formato de sintaxis de la declaración de paquete es:

package pkg1[.pkg2[.pkg3…]];

Por ejemplo, el contenido de un archivo Something.java es

package net.java.util; public class Something{ ... }

Entonces su ruta debería sernet/java/util/Something.javaSe guarda de esta manera. La función de package (paquete) es clasificar y guardar diferentes programas de Java, para que puedan ser invocados más fácilmente por otros programas de Java.

Un paquete (package) se puede definir como un grupo de tipos interrelacionados (clases, interfaces, enumeraciones y anotaciones), que proporciona funciones de protección de acceso y gestión de espacios de nombres para estos tipos.

A continuación se muestran algunos paquetes en Java:

  • java.lang- Contiene las clases básicas
  • java.io- Contiene funciones de entrada y salida

Los desarrolladores pueden empaquetar por sí mismos un conjunto de clases e interfaces y definir sus propios paquetes. Además, esto es recomendable en el desarrollo real; cuando hayas completado la implementación de tus clases, agrupar las clases relacionadas permite que otros programadores identifiquen más fácilmente qué clases, interfaces, enumeraciones y anotaciones están relacionadas.

Debido a que el paquete crea un nuevo espacio de nombres (namespace), no habrá conflictos de nombres con ningún nombre de otros paquetes. Usar este mecanismo de paquetes hace más fácil implementar el control de acceso y simplifica la localización de clases relacionadas.


Crear paquetes

Al crear un paquete, debes elegir un nombre apropiado para él. Después, si otro archivo fuente contiene las clases, interfaces, enumeraciones o tipos de anotación proporcionados por este paquete, debes colocar la declaración de este paquete al inicio de ese archivo fuente.

La declaración de paquete debe estar en la primera línea del archivo fuente. Cada archivo fuente solo puede tener una declaración de paquete, y cada tipo de este archivo se aplica a ella.

Si un archivo fuente no tiene una declaración de paquete, entonces sus clases, funciones, enumeraciones, anotaciones, etc., se colocarán en un paquete sin nombre (unnamed package).

Ejemplo

Veamos un ejemplo: este ejemplo crea un paquete llamado animals. Normalmente se usan letras minúsculas para nombrarlo, a fin de evitar conflictos con los nombres de clases e interfaces.

Agrega una interfaz (interface) al paquete animals:

Código del archivo Animal.java:

/*Nombre de archivo: Animal.java*/ package animals; interface Animal { public void eat(); public void travel(); }

A continuación, agrega la implementación de esta interfaz en el mismo paquete:

Código del archivo MammalInt.java:

package animals; /*Nombre de archivo: MammalInt.java*/ public class MammalInt implements Animal{ public void eat(){ System.out.println("Mammal eats"); } public void travel(){ System.out.println("Mammal travels"); } public int noOfLegs(){ return 0; } public static void main(String args[]){ MammalInt m = new MammalInt(); m.eat(); m.travel(); } }

Luego, compila estos dos archivos y colócalos en un subdirectorio llamado animals. Usa el siguiente comando para ejecutarlos:

$ mkdir animals
$ cp Animal.class  MammalInt.class animals
$ java animals/MammalInt
Mammal eats
Mammal travel

La palabra clave import

Para poder usar los miembros de un paquete, necesitamos importar explícitamente ese paquete en el programa Java.

En Java,importla palabra clave se utiliza para importar tipos definidos en otras clases o paquetes, de modo que estos tipos se puedan usar en el archivo fuente actual.

importLa palabra clave se utiliza para introducir clases, interfaces o miembros estáticos de otros paquetes. Permite usar directamente en el código las clases de otros paquetes, sin necesidad de especificar completamente el nombre del paquete de la clase.

En un archivo fuente de Java, la declaración import debe estar al comienzo del archivo fuente. Su formato de sintaxis es:

import package1[.package2…].(classname|*);

La declaración import se coloca después de la declaración package:

//La primera línea que no sea un comentario es la declaración package package com.example; //La declaración import introduce clases de otros paquetes import java.util.ArrayList; import java.util.List; //La definición de la clase public class MyClass { //Los miembros y métodos de la clase }

Si dentro de un paquete una clase quiere usar otra clase del mismo paquete, el nombre del paquete se puede omitir.

Se puede usar la declaración import para introducir una clase específica:

import com.ejemplo.MyClass;

De esta manera, puedes usar directamente los métodos, variables o constantes de la clase MyClass en el archivo fuente actual.

También se puede usar el comodín*para importar todo el paquete o los subpaquetes del paquete:

import com.ejemplo.mypackage.*;

De esta manera, puedes importarcom.ejemplo.mypackagetodas las clases del paquete, y así usar los métodos, variables o constantes de cualquier clase de ese paquete en el archivo fuente actual. Ten en cuenta que al usar el comodín*al importar todo el paquete, solo se importan las clases del paquete, no los subpaquetes del paquete.

Al importar una clase o paquete, debes proporcionar el nombre completamente calificado de la clase o del paquete. El nombre completamente calificado incluye la combinación del nombre del paquete y el nombre de la clase, con un punto.que los separa.

Ejemplo

import java.util.ArrayList; // Importa la clase ArrayList del paquete java.util
import java.util.*; // Importa todas las clases del paquete java.util

import com.example.MyClass; // Importa la clase MyClass del paquete com.example
import com.example.*; // Importa todas las clases del paquete com.example

Ejemplo

El siguiente paquete payroll ya contiene la clase Employee. A continuación, agrega una clase Boss al paquete payroll. Cuando la clase Boss hace referencia a la clase Employee, puede omitir el prefijo payroll. El ejemplo de la clase Boss es el siguiente.

Código del archivo Boss.java:

package payroll; public class Boss { public void payEmployee(Employee e) { e.mailCheck(); } }

¿Qué pasaría si la clase Boss no está en el paquete payroll? La clase Boss debe usar uno de los siguientes métodos para hacer referencia a las clases de otros paquetes.

Usar el nombre completo de la clase, por ejemplo:

payroll.Employee

usarimportIntroducir con la palabra clave, usando el comodín*:

import payroll.*;

Usarimportla palabra clave para introducir la clase Employee:

import payroll.Employee;

Nota:

Un archivo de clase puede contener cualquier número de declaraciones import. La declaración import debe estar después de la declaración del paquete y antes de la declaración de la clase.


Estructura de directorios de package

Colocar clases en un paquete tiene dos resultados principales:

  • El nombre del paquete se convierte en parte del nombre de la clase, como lo hemos comentado anteriormente.
  • El nombre del paquete debe coincidir con la estructura de directorios donde se encuentra el bytecode correspondiente.

A continuación se muestra una forma sencilla de gestionar tus archivos de Java:

Coloca el código fuente de los tipos, como clases e interfaces, en un archivo de texto. El nombre de este archivo es el nombre del tipo, con .java como extensión. Por ejemplo:

//Nombre de archivo: Car.java package vehicle; public class Car { //Implementación de la clase }

Luego, coloca el archivo fuente en un directorio que corresponda al nombre del paquete al que pertenece la clase.

....\vehicle\Car.java

Ahora, el nombre de clase y la ruta correctos serán de la siguiente manera:

  • Nombre de clase -> vehicle.Car

  • Ruta -> vehicle\Car.java (en sistemas Windows)

Normalmente, una empresa usa la forma invertida de su nombre de dominio de Internet como nombre de su paquete. Por ejemplo: si el nombre de dominio es example.com, todos los nombres de paquete comienzan con com.ejemplo. Cada parte del nombre del paquete corresponde a un subdirectorio.

Por ejemplo: hay uncom.ejemplo.testpaquete que contiene un archivo fuente llamado Ejemplo.java; en consecuencia, debería tener la siguiente serie de subdirectorios:

....\com\ejemplo\test\Ejemplo.java

Al compilar, el compilador crea un archivo de salida diferente para cada tipo (clase, interfaz, etc.) definido en el paquete. El nombre del archivo de salida es el nombre del tipo, con .class como extensión. Por ejemplo:

//Nombre de archivo: Ejemplo.java package com.ejemplo.test; public class Ejemplo { } class Google { }

Ahora, compilemos este archivo con la opción -d, de la siguiente manera:

$javac -d . Ejemplo.java

Esto colocará los archivos compilados de la siguiente manera:

.\com\ejemplo\test\Ejemplo.class
.\com\ejemplo\test\Google.class

Puedes importar todos los \com\ejemplo\test\ tipos, como clases, interfaces, etc., definidos en él:

import com.ejemplo.test.*;

Después de la compilación, los archivos .class, al igual que los archivos fuente .java, deben colocarse en directorios que correspondan al nombre del paquete. Sin embargo, no se requiere que la ruta de los archivos .class sea la misma que la ruta de los archivos .java correspondientes. Puedes organizar los directorios de código fuente y de clases por separado.

<path-one>\sources\com\ejemplo\test\Ejemplo.java
<path-two>\classes\com\ejemplo\test\Google.class

De esta manera, puedes compartir tu directorio de clases con otros programadores sin revelar tu código fuente. Gestionar el código fuente y los archivos de clase de esta manera permite que el compilador y la máquina virtual de Java (JVM) encuentren todos los tipos utilizados en tu programa.

La ruta absoluta del directorio de clases se llamaclass path. Se establece en la variable deCLASSPATHsistema.

Si <path-two>\classes es el class path y el nombre del paquete es com.ejemplo.test, el compilador y la JVM buscarán los archivos .class en <path-two>\classes\com\ejemplo\test.

Un class path puede contener varias rutas; las múltiples rutas deben separarse con un separador. De forma predeterminada, el compilador y la JVM buscan en el directorio actual. Los archivos JAR contienen clases relacionadas con la plataforma Java, por lo que sus directorios se incluyen en el class path de forma predeterminada.


Configurar la variable de sistema CLASSPATH

Muestra la variable CLASSPATH actual con el siguiente comando:

  • Plataforma Windows (línea de comandos DOS): C:\> set CLASSPATH
  • Plataforma UNIX (Bourne shell): # echo $CLASSPATH
Elimina el contenido actual de la variable CLASSPATH:
  • Plataforma Windows (línea de comandos DOS): C:\> set CLASSPATH=
  • Plataforma UNIX (Bourne shell): # unset CLASSPATH; export CLASSPATH

Configurar la variable CLASSPATH:

  • Plataforma Windows (línea de comandos DOS): C:\> set CLASSPATH=C:\users\jack\java\classes
  • Plataforma UNIX (Bourne shell): # CLASSPATH=/home/jack/java/classes; export CLASSPATH
Otras extensiones