Для чего нужны пакеты в java
28. Java – Пакеты
В Java пакеты (package) используются для предотвращения конфликтов с названиями, для контроля доступа, для облегчения поиска/нахождения и использования классов, интерфейсов, перечислений и аннотаций и т.д.
Пакеты можно определить как группировку связанных типов (классы, интерфейсы, перечисления и аннотации), предоставляющий защиту доступа и управление пространством имён.
Содержание
Некоторые из существующих пакетов в Java:
Программисты могут определять их пакеты для связывания групп классов/интерфейсов и т.д. Группировка связанных классов, реализованных вами, является хорошим практическим решением, т.к. программист сможет легко определить, что классы, интерфейсы, перечисления и аннотации связаны.
Так как пакет создаёт новое пространство имён, в нём не будет никаких конфликтов с именами в других пактах. Используя пакеты, легче предоставить управление доступом и легче найти связанные классы.
Создание пакета
Как создать пакет в Java? Во время создания пакета вы должны выбрать ему имя и включить оператор package вместе с этим именем поверх каждого исходного файла, который содержит классы, интерфейсы, перечисления и типы аннотаций, которые вы хотите включить в пакет.
Оператор package должен быть первой строкой в исходном файле. Может быть только один запрос package в каждом исходном файле, и он применяется ко всем типам в этом файле.
Если оператор package не использован, тогда классы, интерфейсы, перечисления и типы аннотаций будут помещены в текущий пакет по умолчанию.
Чтобы скомпилировать программы на Java с операторами package, то вам нужно использовать опцию –d, как показано ниже.
Затем в указанном месте назначения создается папка с указанным именем пакета, а файлы скомпилированных классов будут помещены в эту папку.
Пример 1
Давайте взглянем на пример, которые создаёт пакет под названием animals. Полезно использовать имена пакетов с маленькой буквы, чтобы избежать конфликтов с именами классов и интерфейсов.
В следующем примере пакета содержится интерфейс с названием animals.
Теперь давайте реализуем вышеприведённый интерфейс в этом же пакете animals:
А сейчас скомпилируем java-файлы, как показано ниже:
Теперь пакет/папка с именем animals будет создана в текущей директории, и файлы классов будут помещены в неё.
Вы можете запустить файл класса внутри пакета и получить результат, указанный ниже.
Ключевое слово import
Если класс хочет использовать другой класс в том же пакете, то не нужно использовать имя пакета. Классы в одном пакете могут найти друг друга без особого синтаксиса.
Пример 2
Итак, класс под названием Boss добавлен в пакет payroll, который уже содержит Employee. Boss может обратиться к классу Employee без использования префикса payroll, как показано в следующем классе Boss.
Что произойдёт, если класс Employee не будет включен в пакет payroll? Тогда класс Boss должен будет использовать одну из следующих техник для обращения к классу в другом пакете:
Примечание: Файл класса может содержать любое количество операторов импорта (import). Операторы импорта (import) должны появляться после оператора пакета (package) и перед объявлением класса.
Структура директории пакетов
Происходят два явления, когда класс помещён в пакет:
Есть лёгкий способ работы с вашими файлами в Java:
Теперь поместите исходный файл в директорию, имя которой отражает имя пакета, к которому принадлежит класс:
Полноценное имя класса и пути будет выглядеть так:
В общем, компания использует своё обратное доменное имя в Интернете для своих именований пакетов в Java.
Например: доменное имя компании называется apple.com, тогда все имена их пакетов будут начинаться с com.apple. Каждый компонент имени пакета соответствует поддиректории.
Например: у компании есть пакет com.apple.computers, в котором содержится исходный файл Dell.java, тогда он содержится в серии поддиректорий, как указано здесь:
Теперь скомпилируйте это, используя опцию –d:
Файлы скомпилируются следующим образом:
Вы можете импортировать все классы и интерфейсы, определённые в \com\apple\computers\ вот так:
Делая так, становится возможным предоставить доступ к директории классов другим программистам, не раскрывая ваши источники. Вам также нужно распределить файлы классов и источников таким образом, чтобы компилятор и Java Virtual Machine (JVM) могли найти все типы, которые использует ваша программа.
Полный путь к директории классов
Путь класса может включать несколько путей. Множество путей должны быть отделены точкой с запятой (Windows) или двоеточием (Unix). По умолчанию компилятор и JVM ищут текущую директорию и JAR-файл, содержащий классы платформы Java, чтобы эти директории были автоматически включены в путь класса.
Установить системную переменную CLASSPATH
Чтобы отобразить текущую CLASSPATH переменную, используйте следующие команды в Windows и UNIX (Bourne shell):
Чтобы удалить содержимое переменной CLASSPATH, используйте:
Чтобы установить системную переменную CLASSPATH:
Руководство по пакетам Java
Узнайте больше о пакетах на Java
1. введение
В этом кратком руководстве мы рассмотрим основы работы с пакетами на Java. Мы увидим, как создавать пакеты и получать доступ к типам, которые мы помещаем в них.
Мы также обсудим соглашения об именах и то, как это связано с базовой структурой каталогов.
Наконец, мы скомпилируем и запустим наши упакованные классы Java.
2. Обзор пакетов Java
Основными преимуществами этого являются:
Далее давайте посмотрим, как мы можем создавать и использовать Java-пакеты.
3. Создание пакета
Давайте поместим тип в пакет с именем com.baeldung.packages :
Настоятельно рекомендуется помещать каждый новый тип в пакет. Если мы определяем типы и не помещаем их в пакет, они будут отправлены в default или безымянный пакет. Использование пакетов по умолчанию имеет несколько недостатков:
3.1. Соглашения об именовании
Чтобы избежать пакетов с одинаковыми именами, мы следуем некоторым соглашениям об именовании:
Чтобы определить имя пакета на основе организации, мы обычно начинаем с реверсирования URL-адреса компании. После этого соглашение об именовании определяется компанией и может включать названия подразделений и названия проектов.
Затем мы можем дополнительно определить подпакеты этого типа, такие как com.baeldung.packages или com.baeldung.packages.domain.
3.2. Структура каталогов
Пакеты в Java соответствуют структуре каталогов.
Большинство идей помогут создать эту структуру каталогов на основе наших имен пакетов, поэтому нам не нужно создавать их вручную.
4. Использование Членов Пакета
Начнем с определения класса TodoItem в подпакете с именем domain :
4.1. Импорт
Чтобы использовать наш класс TodoItem из класса в другом пакете, нам нужно импортировать его. Как только он будет импортирован, мы сможем получить к нему доступ по имени.
Мы можем импортировать один тип из пакета или использовать звездочку для импорта всех типов в пакете.
Давайте импортируем весь домен подпакет:
Теперь давайте импортируем только класс TodoItem :
JDK и другие библиотеки Java также поставляются со своими собственными пакетами. Мы можем импортировать уже существующие классы, которые мы хотим использовать в нашем проекте таким же образом.
Например, давайте импортируем Java core List interface и ArrayList class:
Затем мы можем использовать эти типы в нашем приложении, просто используя их имя:
Здесь мы использовали наши новые классы вместе с классами ядра Java, чтобы создать List of TodoItems.
4.2. Полное Наименование
Давайте использовать To do Item с полным именем:
5. Компиляция с помощью javac
Давайте начнем с открытия командной строки или терминала и перехода в наш исходный каталог.
Теперь давайте скомпилируем наш com.baeldung.packages.domain.TodoItem класс:
Теперь, когда наш класс TodoItem скомпилирован, мы можем скомпилировать наши классы ToDoList и TodoApp :
Давайте запустим наше приложение, используя полное имя нашего класса TodoApp :
Пакеты Java – назначение и использование
Пакеты Java – это механизм для группировки классов, которые связаны друг с другом, в одну и ту же «группу» (пакет). Когда проект становится больше, например, приложение или API, полезно разделить код на несколько классов, а классы – на несколько пакетов. Тогда становится легче выяснить, где находится определенный класс, который вы ищете.
Пакет подобен каталогу в файловой системе. На самом деле на диске он является каталогом. Все исходные файлы и файлы классов, принадлежащих одному и тому же пакету, находятся в одном каталоге.
Могут содержать подпакеты. Таким образом, могут составлять так называемую структуру пакета, похожую на структуру каталогов. Это дерево пакетов, подпакетов и классов внутри этих классов. Организована как каталоги на вашем жестком диске или как каталоги внутри zip-файла (JAR-файлы).
Вот скриншот примера структуры:
Вверху вы видите каталог с именем “src”. Это исходный корневой каталог. Это не сам пакет. Внутри этого каталога все подкаталоги соответствуют пакетам. Таким образом, «коллекции», «com», «параллелизм» и т. д. – это все пакеты (которые также являются каталогами на диске). На снимке экрана выше они показаны значком папки.
Расширено два пакета подуровня, чтобы вы могли видеть классы внутри. Классы проиллюстрированы с помощью маленького синего круга с буквой C внутри, на скриншоте выше.
Полный путь к подпакету – это его имя со всеми именами пакетов-предков, разделенных точками. Например, полный путь к «навигационному» подпакету:
Точно так же полное имя класса включает имя его пакета. Например, полное имя класса «Page»:
Создание структуры
Чтобы создать пакет, вы должны сначала создать корневой каталог на вашем жестком диске. Он сам по себе не является частью структуры пакета. Содержит все исходные коды, которые должны войти в структуру.
Создав исходный корневой каталог, вы можете начать добавлять в него подкаталоги. Каждый подкаталог соответствует пакету. Вы можете добавить подкаталоги в подкаталоги, чтобы создать более глубокую структуру.
Добавление классов
Чтобы добавить классы, вы должны сделать две вещи:
Первый пункт довольно прост. Создайте корневой каталог источника и внутри него создайте каталоги для каждого пакета и подпакета рекурсивно. Поместите файлы классов в каталог, соответствующий пакету, в который вы хотите добавить его.
Когда вы поместили свой исходный файл в правильный каталог (соответствующий пакету, к которому должен принадлежать класс), вы должны объявить внутри этого файла класса, что он принадлежит этому пакету:
Первая строка в приведенном выше коде – это то, что объявляет класс Page принадлежащим к com.blog.navigation.
Соглашения об именах
Пакеты всегда пишутся строчными буквами. В отличие от классов, где первая буква обычно является заглавной.
Чтобы избежать создания пакетов с такими же именами, как у других общедоступных, рекомендуется начинать иерархию с обратного доменного имени вашей компании. Например, поскольку доменное имя компании – blog.com, надо начать со структуры с именем com.blog. Другими словами, пакет верхнего уровня с именем com с подпакетом внутри называется blog.
Импорт
Если класс A должен использовать класс B, вы должны ссылаться на класс B внутри класса A. Если классы A и B находятся в одном и том же пакете, компилятор будет принимать ссылки между двумя классами:
Если классы A и B находятся в одном и том же пакете, проблем с кодом выше нет. Однако, если класс A и B находятся в разных, класс A должен импортировать класс B, чтобы использовать его:
Это первая строка в примере, которая импортирует класс B. В примере предполагается, что класс B находится в пакете с именем anotherpackage.
Если бы класс B находился в подпакете другого пакета, вам пришлось бы перечислить полный путь пакета и подпакета к классу B. Например, если бы класс B находился в пакете anotherpackage.util, то оператор import выглядел бы так:
Импорт всех классов из другого пакета
Если вам нужно использовать много классов из определенного пакета, их импорт по одному приводит к большому количеству операторов импорта. Можно импортировать все классы, используя символ * вместо имени класса:
Использование классов через определенное имя
Можно использовать класс из другого пакета, не импортируя его с помощью оператора импорта. Вы можете написать полное имя его, а не просто имя самого класса. Полное имя класса состоит из полного пути пакета до подкласса, содержащего класс, а также самого имени класса. Полное имя класса – это то, что вы написали бы в операторе импорта. Например:
Вы можете использовать это полное имя класса для ссылки на класс TimeUtil внутри другого класса, например так:
Пакетное разделение
Официального стандарта для этого нет, но есть два широко используемых метода.
Разделить на слои
Первый метод состоит в том, чтобы разделить классы после определения, к какому «слою» приложения они принадлежат. Например, ваше приложение может иметь слой базы данных. Тогда вы создадите пакет базы данных. Все классы, участвующие в обмене данными с базой данных, будут расположены в нем.
Разделить по функциональности приложения
Второй метод – разделить ваши классы в зависимости от того, к какой части функциональности приложения они принадлежат. Таким образом, если ваше приложение имеет функциональную область, которая рассчитывает пенсии, вы можете создать пакет с именем pension. Все классы, так или иначе участвующие в пенсионных расчетах, будут включены в него (или подпакеты, если число классов в пенсии станет большим).
В сочетании с доменным именем структура для пенсионного пакета будет:
Всего три пакета, два вложенных в другие.
Метод «деления по функциональности приложения» имеет тенденцию работать лучше, чем «деление по слоям», поскольку в вашем приложении растет число классов.
Вместо того, чтобы иметь фиксированное количество пакетов слоев, число которых продолжает расти, вы получаете растущее число пакетов функциональности приложения с меньшим количеством классов внутри.
Встроенные
Платформа поставляется с множеством встроенных пакетов. Они содержат классы для самых разных целей, которые часто нужны программистам, например, чтение и запись файлов с локального жесткого диска, отправка и получение данных по сетям и Интернету, подключение к базам данных и многое, многое другое.
Пакеты (packages)
— Привет, Амиго! Сегодня я расскажу тебе про пакеты.
— Файлы в компьютере группируются по папкам. Классы в Java (а каждый класс лежит в отдельном файле) группируются по пакетам, которые являются папками на диске. Ничего принципиально нового. Но есть два замечания
— Первое. «Полным уникальным именем класса» является «имя пакета» + «имя класса». Примеры:
Полное уникальное имя | Имя пакета | Имя класса |
---|---|---|
java.io.FileInputStream | java.io | FileInputStream |
java.lang.String | java.lang | String |
java.util.ArrayList | java.util | ArrayList |
org.apache.tomcat.Servlet | org.apache.tomcat | Servlet |
Cat | отсутствует | Cat |
— Полное имя класса всегда уникально!
— Каждый раз писать длинное имя, например java.util.ArrayList, очень неудобно. Поэтому в Java добавили возможность «импортировать классы». В своем коде ты можешь пользоваться коротким именем других классов, но ты должен в начале своего класса явно указать, какой именно класс будет использоваться.
— Делается это конструкцией вида « import java.util.ArrayList; »
— В начале класса, сразу после объявления package, ты можешь указать какой именно класс скрывается за ArrayList, который ты используешь у себя в коде.
— Зачем такая сложность? Что могут быть классы с одинаковыми именами?
— Вот еще одна аналогия. У тебя в коллективе есть Серега и никаких проблем с общением – все знают кто это. Но если бы их было трое, то чтобы их различать пришлось бы использовать полные уникальные имена.
В Java принято давать классам и пакетам осмысленные имена. Многие компании выпускают свои библиотеки (набор классов) и, чтобы не было путаницы, называют пакеты этих классов по имени компании/сайта:
Модуль 2. Урок 4. Пакеты в Java. — Введение в Java
Что такое пакеты?
Пакеты, по сути, являются файловой и логической структурой связей классов в мире java. Очень схоже с файловой системой компьютера. На уровне файловой системы пакеты это и есть папки, в которых лежат другие папки (подпакеты) и классы. Но пакеты не всегда описывают напрямую всю структуру проекта. На практике проект включает в себя различные ресурсы, а структура папок, которую мы назначаем как имена пакетов для наших классов — может быть лишь небольшой частью целого проекта. Ведь, кроме основного кода в пакетах, у нас должны быть еще и тесты, библиотеки или даже другие языки программирования в проекте в целом.
Как аналогию, можно привести пример с адресами.
Что такое пакет для класса
Для класса его пакет — это его местоположение в проекте, относительно других классов. Благодаря разделению классов на несколько пакетов — мы организовываем структуру программы.
Сильно забегая вперед скажу, что такое разделение нужно не только для красоты, но и для ограничения доступа к некоторым членам класса. Например:
Как создать класс внутри пакета?
Рассмотрим этот процесс поэтапно.
Сначала пишем имя любимого редактора в терминале, потом существующий путь, а потом имя будущего текстового файла. Пример для редактора nano :
Или с помощью sublime:
Если команда subl не найдена и Вы уверены в том, что sublime установлен — проверьте, в переменных среды окружения, наличие прописанного пути к папке, в которой лежит subl.
Можно и обычным блокнотом создать нужный файл в нужной директории. Создать сам файл можно и любым другим удобным для вас способом.
Файл создан. Но класса в нем нет. Создадим класс:
Теперь у нас есть и файл в нужной папке, и класс в файле. Но сам класс ничего не знает про то, что он принадлежит некому пакету. Исправим это:
Не забываем сохранять файл!
Ключевые моменты верного создания класса внутри пакета:
Корень пакетов
А как же задать корневой каталог (папку) как основу пакетов, в котором уже и происходит ветвление этих всех под-пакетов (под-папок)? Почему, например, папка io является корнем для классов проекта, а папка src — не является пакетом, да и вообще не входит в пакетную структуру проекта?
Пример содержимого класса OneMoreClass.java :
Пример содержимого класса SomeView.java :
Имена пакетов
Например, package com.MySuperLongPackageName.view — плохая практика именования пакетов.
Совокупность имен под-пакетов делает проект уникальным, не похожим на миллионы других. Даже если, в каждом проекте в мире, 100% будет класс Main.java — то они маловероятно пересекутся и помешают друг-другу. Но даже если пересекутся — это решаемо, рассмотрим это в дальнейших примерах.
Применение пакетов
Адреса (пакеты) классам, в нашем проекте, мы уже выдали. Они нужны для доступа классов друг к другу.
Как уже было сказано выше — пакет можно сравнить с адресом. Рассмотрим это на примере ветвления папок(пакетов).
Но прописывание таких длинных путей ( io.hexlet.xo.view.SomeView ) — просто не удобно. Поэтому, к нам на выручку, приходит импортирование.
Импортирование пакетов
Перепишем предыдущий пример с импортированием любых классов из пакета io.hexlet.xo.view :
Импортирование по умолчанию
Обратите внимание на строку System.out.println(«Some very important message!»); в классе SomeView :
Статическое импортирование
Как компилировать классы в пакетах
Как запускать классы в пакетах
Именно с него начинается работа самостоятельной java-программы. В остальных классах одной программы — этот метод не нужен.
А для запуска «пакетного» класса на исполнение требуется иной подход.
Полезные ссылки: