В Java пакеты (package) используются для предотвращения конфликтов с названиями, для контроля доступа, для облегчения поиска/нахождения и использования классов, интерфейсов, перечислений и аннотаций и т.д.

Пакеты можно определить как группировку связанных типов (классы, интерфейсы, перечисления и аннотации), предоставляющий защиту доступа и управление пространством имён.

Некоторые из существующих пакетов в Java:

  • java.lang – связывает фундаментальные классы.
  • java.io – классы для ввода и выводные функции связаны в этом пакете.

Программисты могут определять их пакеты для связывания групп классов/интерфейсов и т.д. Группировка связанных классов, реализованных вами, является хорошим практическим решением, т.к. программист сможет легко определить, что классы, интерфейсы, перечисления и аннотации связаны.

Так как пакет создаёт новое пространство имён, в нём не будет никаких конфликтов с именами в других пактах. Используя пакеты, легче предоставить управление доступом и легче найти связанные классы.

Создание пакета

Как создать пакет в Java? Во время создания пакета вы должны выбрать ему имя и включить оператор package вместе с этим именем поверх каждого исходного файла, который содержит классы, интерфейсы, перечисления и типы аннотаций, которые вы хотите включить в пакет.

Оператор package должен быть первой строкой в исходном файле. Может быть только один запрос package в каждом исходном файле, и он применяется ко всем типам в этом файле.

Если оператор package не использован, тогда классы, интерфейсы, перечисления и типы аннотаций будут помещены в текущий пакет по умолчанию.

Чтобы скомпилировать программы на Java с операторами package, то вам нужно использовать опцию –d, как показано ниже.

javac -d Destination_folder file_name.java

Затем в указанном месте назначения создается папка с указанным именем пакета, а файлы скомпилированных классов будут помещены в эту папку.

Пример 1

Давайте взглянем на пример, которые создаёт пакет под названием animals. Полезно использовать имена пакетов с маленькой буквы, чтобы избежать конфликтов с именами классов и интерфейсов.

В следующем примере пакета содержится интерфейс с названием animals.

/* File name : Animal.java */
package animals;

interface Animal {
   public void eat();
   public void travel();
}

Теперь давайте реализуем вышеприведённый интерфейс в этом же пакете animals:

package animals;
/* File name : MammalInt.java */

public class MammalInt implements Animal {

   public void eat() {
      System.out.println("Млекопитающее кушает");
   }

   public void travel() {
      System.out.println("Млекопитающее путешествует");
   } 

   public int noOfLegs() {
      return 0;
   }

   public static void main(String args[]) {
      MammalInt m = new MammalInt();
      m.eat();
      m.travel();
   }
}

А сейчас скомпилируем java-файлы, как показано ниже:

$ javac -d . Animal.java 
$ javac -d . MammalInt.java

Теперь пакет/папка с именем animals будет создана в текущей директории, и файлы классов будут помещены в неё.

Вы можете запустить файл класса внутри пакета и получить результат, указанный ниже.

Mammal eats
Mammal travels

Ключевое слово import

Если класс хочет использовать другой класс в том же пакете, то не нужно использовать имя пакета. Классы в одном пакете могут найти друг друга без особого синтаксиса.

Пример 2

Итак, класс под названием Boss добавлен в пакет payroll, который уже содержит Employee. Boss может обратиться к классу Employee без использования префикса payroll, как показано в следующем классе Boss.

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

Что произойдёт, если класс Employee не будет включен в пакет payroll? Тогда класс Boss должен будет использовать одну из следующих техник для обращения к классу в другом пакете:

  • Можно использовать полноценное имя класса. К примеру:
payroll.Employee
  • Импорт пакета. В Java пакет может быть импортирован с помощью ключевого слова import и wild card. (*). Например:
import payroll.*;
  • Сам класс можно импортировать с помощью ключевого слова import. Взглянем:
import payroll.Employee;

Примечание: Файл класса может содержать любое количество операторов импорта (import). Операторы импорта (import) должны появляться после оператора пакета (package) и перед объявлением класса.

Структура директории пакетов

Происходят два явления, когда класс помещён в пакет:

  • Имя пакета в Java становится частью имени класса, как мы только что выяснили в прошлой секции.
  • Имя пакета должно соответствовать со структурой директории, где находится соответствующий байт-код.

Есть лёгкий способ работы с вашими файлами в Java:

Поместите исходный код для класса, интерфейса, перечисления или типа аннотации в текстовый файл, имя которого является простым именем типа с расширением .java.

К примеру:

// File Name :  Car.java
package vehicle;

public class Car {
   // Class implementation.   
}

Теперь поместите исходный файл в директорию, имя которой отражает имя пакета, к которому принадлежит класс:

....\vehicle\Car.java

Полноценное имя класса и пути будет выглядеть так:

  • Имя класса – vehicle.Car
  • Путь к файлу – vehicle\Car.java (в Windows)

В общем, компания использует своё обратное доменное имя в Интернете для своих именований пакетов в Java.

Например: доменное имя компании называется apple.com, тогда все имена их пакетов будут начинаться с com.apple. Каждый компонент имени пакета соответствует поддиректории.

Например: у компании есть пакет com.apple.computers, в котором содержится исходный файл Dell.java, тогда он содержится в серии поддиректорий, как указано здесь:

....\com\apple\computers\Dell.java

Компилятор создаёт во время компиляции другой файл вывода для каждого класса, интерфейса и перечисления, определённых в нём. Обычное имя файла вывода состоит из имени типа и расширения .class.

Например:

// File Name: Dell.java
package com.apple.computers;

public class Dell {
}

class Ups {
}

Теперь скомпилируйте это, используя опцию –d:

$javac -d . Dell.java

Файлы скомпилируются следующим образом:

.\com\apple\computers\Dell.class
.\com\apple\computers\Ups.class

Вы можете импортировать все классы и интерфейсы, определённые в \com\apple\computers\ вот так:

import com.apple.computers.*;

Как и исходные файлы .java, скомпилированные файлы .class должны быть в серии директорий, которые отражают имя пакета. Однако путь к файлам .class не должен быть таким же, как путь к исходным файлам .java. Вы можете разделить директории для классов и источников вот так:

\sources\com\apple\computers\Dell.java

\classes\com\apple\computers\Dell.class

Делая так, становится возможным предоставить доступ к директории классов другим программистам, не раскрывая ваши источники. Вам также нужно распределить файлы классов и источников таким образом, чтобы компилятор и Java Virtual Machine (JVM) могли найти все типы, которые использует ваша программа.

Полный путь к директории классов \classes называется путь класса и устанавливается с системной переменной CLASSPATH. И компилятор, и JVM создают путь к вашим файлам .class, добавляя имя пакета к пути класса.

Допустим, \classes – это путь класса, а имя пакета com.apple.computers, тогда компилятор и JVM будут искать файлы .class в \classes\com\apple\computers.

Путь класса может включать несколько путей. Множество путей должны быть отделены точкой с запятой (Windows) или двоеточием (Unix). По умолчанию компилятор и JVM ищут текущую директорию и JAR-файл, содержащий классы платформы Java, чтобы эти директории были автоматически включены в путь класса.

Установить системную переменную CLASSPATH

Чтобы отобразить текущую CLASSPATH переменную, используйте следующие команды в Windows и UNIX (Bourne shell):

  • Для Windows – C:\> set CLASSPATH
  • Для UNIX – % echo $CLASSPATH

Чтобы удалить содержимое переменной CLASSPATH, используйте:

  • Для Windows – C:\> set CLASSPATH =
  • Для UNIX – % unset CLASSPATH; export CLASSPATH

Чтобы установить системную переменную CLASSPATH:

  • Для Windows – set CLASSPATH = C:\users\jack\java\classes
  • Для UNIX – % CLASSPATH = /home/jack/java/classes; export CLASSPATH
  • Оглавление