Перейти к содержанию

Руководство по пакетам в Java

В этом кратком руководстве рассмотрим основы пакетов в Java, увидим, как создавать пакеты и получать доступ к классам, которые помещаем в них.

Также обсудим соглашения об именах и их связь с базовой структурой каталогов.

Наконец, скомпилируем и запустим упакованные классы Java.

Обзор пакетов Java

В Java используются пакеты для группировки связанных классов, интерфейсов и подпакетов.

Основными преимуществами этого являются:

  • облегчение поиска связанных классов – пакеты обычно содержат классы, которые логически связаны;
  • отсутствие конфликтов имен – пакет поможет однозначно идентифицировать класс; например, могут быть классы ru.javamaster.Application и com.example.Application;
  • управление доступом – можно контролировать видимость и доступ к классам, комбинируя пакеты и модификаторы доступа.

Далее посмотрим, как можно создавать и использовать пакеты Java.

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

Чтобы создать пакет, необходимо использовать оператор package, добавив его в качестве самой первой строки кода в файле.

Поместим класс в пакет с именем ru.javamaster.packages:

package ru.javamaster.packages;

Настоятельно рекомендуется помещать каждый новый класс в пакет. Если определим классы и не поместим их в пакет, они попадут в пакет по умолчанию или безымянный пакет. Использование пакетов по умолчанию имеет несколько недостатков:

  • теряется преимущество пакетной структуры и нельзя иметь подпакеты;
  • нельзя импортировать классы в пакете по умолчанию из других пакетов;
  • области доступа protected и package-private будут бессмысленными.

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

Поэтому следует избегать использования безымянных пакетов или пакетов по умолчанию в реальных приложениях.

Соглашения об именах

Чтобы избежать пакетов с одинаковыми именами, необходимо следовать некоторым соглашениям об именах:

  • определяем имена пакетов в нижнем регистре;
  • имена пакетов разделены точкой;
  • имена определяются компанией или организацией, которые их создают.

Чтобы определить имя пакета на основе организации, обычно начинаем с обращения URL-адреса компании. После этого соглашение об именовании определяется компанией и может включать названия подразделений и названия проектов.

Например, чтобы создать пакет из www.javamaster.ru, давайте перевернем его:

ru.javamaster

Затем можно дополнительно определить его подпакеты, например ru.javamaster.packages или ru.javamaster.packages.domain.

Структура каталогов

Пакеты в Java соответствуют структуре каталогов.

Каждый пакет и подпакет имеет собственный каталог. Для пакета ru.javamaster.packages должна быть структура каталогов ru -> javamaster -> packages.

Большинство IDE помогут создать эту структуру каталогов на основе имен наших пакетов, поэтому не нужно создавать их вручную.

Использование членов пакета

Начнем с определения класса TodoItem в подпакете с именем domain:

package ru.javamaster.packages.domain;

public class TodoItem {
    private Long id;
    private String description;
    
    // стандартные геттеры и сеттеры
}

Импорт

Чтобы использовать класс TodoItem из класса в другом пакете, нужно его импортировать. После импорта можно получить к нему доступ по имени.

Можно импортировать один класс из пакета или использовать звездочку для импорта всех классов в пакете.

Давайте импортируем весь подпакет домена:

import ru.javamaster.packages.domain.*;

Теперь импортируем только класс TodoItem:

import ru.javamaster.packages.domain.TodoItem;

JDK и другие библиотеки Java поставляются с собственными пакетами. Таким же образом можно импортировать уже существующие классы, которые хотим использовать в проекте.

Например, давайте импортируем базовый интерфейс Java List и класс ArrayList:

import java.util.ArrayList;
import java.util.List;

Затем можно использовать эти классы в приложении, просто используя их имена:

public class TodoList {
    private List<TodoItem> todoItems;

    public void addTodoItem(TodoItem todoItem) {
        if (todoItems == null) {
            todoItems = new ArrayList<TodoItem>();
        }
        todoItems.add(todoItem);
    }
}

Здесь использовали наши новые классы вместе с базовыми классами Java для создания списка задач.

Полное имя

Иногда можно использовать два класса с одинаковыми именами из разных пакетов. Например, можно использовать как java.sql.Date, так и java.util.Date. Когда сталкиваемся с конфликтами имен, нужно использовать полное имя класса по крайней мере для одного из классов.

Давайте используем TodoItem с полным именем:

public class TodoList {
    private List<ru.javamaster.packages.domain.TodoItem> todoItems;

    public void addTodoItem(ru.javamaster.packages.domain.TodoItem todoItem) {
        if (todoItems == null) {
            todoItems = new ArrayList<ru.javamaster.packages.domain.TodoItem>();
        }todoItems.add(todoItem);
    }

    // standard getters and setters
}

Компиляция с помощью javac

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

Сначала нужно скомпилировать класс TodoItem, потому что класс TodoList зависит от него.

Начнем с открытия командной строки или терминала и перехода в наш исходный каталог. Теперь скомпилируем наш класс ru.javamaster.packages.domain.TodoItem:

> javac ru/javamaster/packages/domain/TodoItem.java

Если класс компилируется корректно, мы не увидим сообщений об ошибках, а файл TodoItem.class должен появиться в каталоге ru/javamaster/packages/domain.

Для типов, которые ссылаются на типы в других пакетах, необходимо использовать флаг -classpath, чтобы сообщить команде javac, где найти другие скомпилированные классы.

Теперь, когда класс TodoItem скомпилирован, можно скомпилировать классы TodoList и TodoApp:

> javac -classpath . ru/javamaster/packages/*.java

Мы не должны видеть никаких сообщений об ошибках, но найти два файла классов в каталоге ru/javamaster/packages.

Запустим приложение, используя полное имя класса TodoApp:

> java ru.javamaster.packages.TodoApp

Вывод должен выглядеть так:

Заключение

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

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

Наконец, рассмотрели, как скомпилировать и запустить приложение с пакетами с помощью команд javac и java.

Полный код примера доступен на GitHub.

Оригинал