Package java что это
Перейти к содержимому

Package java что это

  • автор:

Пакеты

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

В следующем примере мы демонстрируем как добавить класс MyFirstApp в пакет lesson1 .

Для добавления класса в пакет, используется оператор package , который задается всегда первой строкой в файле. А также этот класс должен находиться в одноименном нашему пакету каталоге — lesson1 . Вот и все.

package lesson1; public class MyFirstApp < public static void main(String[] args) throws Exception < System.out.print("Hello world. "); >>

Java также предоставляет возможность создания многоуровневого пакета. В этом примере мы добавляем класс MyFirstApp в пакет com.examclouds.javabasics.lesson1 и соответственно в каталог com/examclouds/javabasics/lesson1 .

package com.examclouds.javabasics.lesson1; public class MyFirstApp < public static void main(String[] args) throws Exception < System.out.print("Hello world. "); >>

Существуют также правила для наименования пакетов. Для коммерческих проектов пакет должен начинаться с com, потом следует имя организации и название проекта. Потом пакеты обычно именуются по какому-то функциональному признаку. В примере 2 наименование пакета соответствует этому правилу.

Полное имя класса включает в себя название пакета. В примере 1 полное имя класса — lesson1.MyFirstApp , а в примере 2 — com.examclouds.javabasics.lesson1.MyFirstApp .

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

2. Импорт пакетов

Хорошей практикой считается добавлять классы в пакеты. Но так как полное имя класса включает в себя имя пакета, в коде это может привести к достаточно длинным строкам, что крайне неудобно. Для решения этой проблемы в Java придуман такой механизм как импорт. Оператор import позволяет импортировать класс, после чего к нему можно обращаться просто по имени.

2.1. Использование класса из другого пакета

Рассмотрим пример, в котором имеется два класса находящихся в разных пакетах — first.Example1 и second.Example2 :

package first; public class Example1 < public static void main(String[] args) < second.Example2 example2 = new second.Example2(); System.out.print("Done!"); >>
package second; public class Example2

Класс first.Example1 создает экземпляр объекта second.Example2 , указывая его полное имя. Очевидно, что указывать полное имя класса не очень удобно, особенно если класс находится в многоуровневом пакете.

2.2. Использование оператора import

Перепишем класс first.Example1 используя оператор import :

package first; import second.Example2; public class Example1 < public static void main(String[] args) < Example2 example2 = new Example2(); System.out.print("Done!"); >> 

В языке Java операторы import всегда пишутся после оператора package , и перед определением класса.

Разные варианты написания import:

import java.util.regex.Matcher; import java.time.*;

Существует один пакет, классы которого импортируются в код по умолчанию. Это пакет jаva.lang, в котором находятся наиболее часто используемые классы.

Вы можете импортировать два пакета, в которых находятся классы с одинаковыми именами. Но обращаться к ним по короткому имени будет ошибкой — компилятор не сможет определить какой именно класс вам нужен. Поэтому к таким классам придется обращаться только по полному имени.

При импорте пакета, доступны только publiс классы этого пакета. Например, в следующем примере класс MyClass импортирует весь пакет p1 . Но ему будут доступен только AClass . BClass недоступен, так как он не public .

package p1; public class AClass < >class BClass
package p2; import p1.*; public class MyClass < public static void main(String[] args) < AClass aClass = new AClass(); BClass bClass = new BClass(); //ошибка компиляции. Класс недоступен, т. к. он не public >>
  1. Используем оператор package для объявления пакета, который задается всегда первой строкой в файле.
  2. Если оператора package нет, то классы добавляются в пакет по умолчанию, у которого нет имени.
  3. Класс должен находиться в одноименном нашему пакету каталоге файловой системы.
  4. Можно (и нужно) создавать иерархию пакетов. Для разделения используется точка.
  5. Один пакет может содержать множество классов.
  6. Полное имя класса включает в себя название пакета.
  7. Пакеты служат и для управления доступностью объектов.
  8. В языке Java операторы import всегда пишутся после оператора package , и перед написанием класса.
  9. Классы пакета jаva.lang импортируются компилятором неявно.

Презентацию с видео можно скачать на Patreon .

  • Создание первого приложения
  • Установка JDK
  • Команды командной строки (CMD)
  • Компиляция и запуск приложения из командной строки
  • Компиляция с помощью -sourcepath
  • Classpath
  • JAR-Файлы
  • Аргументы командной строки
  • Создание проекта в IntelliJ IDEA
  • Задания

Package java что это

Как правило, в Java классы объединяются в пакеты. Пакеты позволяют организовать классы логически в наборы. По умолчанию java уже имеет ряд встроенных пакетов, например, java.lang , java.util , java.io и т.д. Кроме того, пакеты могут иметь вложенные пакеты.

Организация классов в виде пакетов позволяет избежать конфликта имен между классами. Ведь нередки ситуации, когда разработчики называют свои классы одинаковыми именами. Принадлежность к пакету позволяет гарантировать однозначность имен.

Чтобы указать, что класс принадлежит определенному пакету, надо использовать директиву package , после которой указывается имя пакета:

package название_пакета;

Как правило, названия пакетов соответствуют физической структуре проекта, то есть организации каталогов, в которых находятся файлы с исходным кодом. А путь к файлам внутри проекта соответствует названию пакета этих файлов. Например, если классы принадлежат пакету mypack, то эти классы помещаются в проекте в папку mypack.

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

Например, создадим в папке для исходных файлов каталог study . В нем создадим файл Program.java со следующим кодом:

package study; public class Program < public static void main(String[] args) < Person kate = new Person("Kate", 32); kate.displayInfo(); >> class Person < String name; int age; Person(String name, int age)< this.name = name; this.age = age; >void displayInfo() < System.out.printf("Name: %s \t Age: %d \n", name, age); >>

Директива package study в начале файла указывает, что классы Program и Person, которые здесь определены, принадлежат пакету study.

Когда мы работаем в среде разработки, например, в Netbeans, то IDE берет на себя все вопросы компиляции пакетов и входящих в них файлов. Соответственно нам достаточно нажать на кнопку, и все будет готово. Однако если мы компилируем программу в командной строке, то мы можем столкнуться с некоторыми трудностями. Поэтому рассмотрим этот аспект.

Для компиляции программы вначале в командной строке/терминале с помощью команды cd перейдем к папке, где находится каталог study.

cd C:\java

Например, в моем случае это каталог C:\java (то есть файл с исходным кодом расположен по пути C:\java\study\Program.java).

Для компиляции выполним команду

javac study\Program.java

После этого в папке study появятся скомпилированные файлы Program.class и Person.class. Для запуска программы выполним команду:

java study.Program

Компиляция пакетов в Java

Импорт пакетов и классов

Если нам надо использовать классы из других пакетов, то нам надо подключить эти пакеты и классы. Исключение составляют классы из пакета java.lang (например, String ), которые подключаются в программу автоматически.

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

java.util.Scanner in = new java.util.Scanner(System.in);

То есть мы указываем полный путь к файлу в пакете при создании его объекта. Однако такое нагромождение имен пакетов не всегда удобно, и в качестве альтернативы мы можем импортировать пакеты и классы в проект с помощью директивы import , которая указывается после директивы package:

package study; import java.util.Scanner; // импорт класса Scanner public class Program < public static void main(String[] args) < Scanner in = new Scanner(System.in); >>

Директива import указывается в самом начале кода, после чего идет имя подключаемого класса (в данном случае класса Scanner).

В примере выше мы подключили только один класс, однако пакет java.util содержит еще множество классов. И чтобы не подключать по отдельности каждый класс, мы можем сразу подключить весь пакет:

import java.util.*; // импорт всех классов из пакета java.util

Теперь мы можем использовать любой класс из пакета java.util.

Возможна ситуация, когда мы используем два класса с одним и тем же названием из двух разных пакетов, например, класс Date имеется и в пакете java.util , и в пакете java.sql . И если нам надо одновременно использовать два этих класса, то необходимо указывать полный путь к этим классам в пакете:

java.util.Date utilDate = new java.util.Date(); java.sql.Date sqlDate = new java.sql.Date();

Статический импорт

В java есть также особая форма импорта — статический импорт. Для этого вместе с директивой import используется модификатор static :

package study; import static java.lang.System.*; import static java.lang.Math.*; public class Program < public static void main(String[] args) < double result = sqrt(20); out.println(result); >>

Здесь происходит статический импорт классов System и Math. Эти классы имеют статические методы. Благодаря операции статического импорта мы можем использовать эти методы без названия класса. Например, писать не Math.sqrt(20) , а sqrt(20) , так как функция sqrt() , которая возвращает квадратный корень числа, является статической. (Позже мы рассмотрим статические члены класса).

То же самое в отношении класса System: в нем определен статический объект out , поэтому мы можем его использовать без указания класса.

Пакеты — Java: Введение в ООП

Реальные программы на Java состоят из сотен и тысяч классов! Часть этих классов добавляется программистами проекта, но многие приходят вместе с библиотеками, используемыми внутри. Например, только библиотека Apache Commons Lang включает в себя около сотни классов.

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

При таких размерах легко возникают ситуации, когда разные программисты создают классы с одинаковыми именами. Если два таких класса окажутся внутри одного проекта, то он перестанет компилироваться. Иногда мы можем просто переименовать один из классов, но что если классы пришли из библиотек, которые мы используем? Здесь уже без вариантов.

Проблема конфликта имен актуальна для всех языков программирования и решение у всех примерно одинаковое. Для этого вводится система модулей, которая позволяет изолировать классы разных проектов, даже если у них одинаковые имена. В Java такая система называется пакетами.

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

Пакеты позволяют группировать похожие классы или даже отдельные проекты. Даже стандартная библиотека Java это не просто набор классов, это набор пакетов, внутри которых уже находятся классы. Например, встроенный пакет java.time содержит классы для работы с датой и временем:

// Импорт позволяет обращаться по прямому имени import java.time.LocalDate; import java.time.Month; import java.time.temporal.ChronoUnit; public class App  public static void main(String[] args)  LocalDate dateFrom = LocalDate.of(2017, Month.MAY, 24); LocalDate dateTo = LocalDate.of(2017, Month.JULY, 29); long noOfDaysBetween = ChronoUnit.DAYS.between(dateFrom, dateTo); System.out.println(noOfDaysBetween); > > 

В коде выше импортируется три класса из пакета java.time. Причем один из них из вложенного пакета java.time.temporal. Импортирование позволяет обращаться к классу по его имени, иначе пришлось бы писать полное имя (fully qualified): java.time.LocalDate.of(. ) . Так тоже можно, но код получается захламленным, его сложнее читать.

Существует еще один способ импорта – с помощью * . Тогда код будет выглядеть немного по-другому:

import java.time.*; import java.time.temporal.*; public class App  public static void main(String[] args)  var dateFrom = LocalDate.of(2017, Month.MAY, 24); var dateTo = LocalDate.of(2017, Month.JULY, 29); var noOfDaysBetween = ChronoUnit.DAYS.between(dateFrom, dateTo); System.out.println(noOfDaysBetween); > > 

* импортирует весь пакет целиком, то есть внутри класса мы можем обратиться ко всем классам импортируемого пакета напрямую. Может показаться, что такой способ удобнее всего, так как не нужно импортировать каждый класс по отдельности. Но тогда возникает две проблемы:

  1. Импортируемые классы из разных мест могут пересечься по именам
  2. Непонятно, кто и откуда был импортирован

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

Помимо java.time в Java еще есть множество других пакетов, например java.nio, java.util, java.net и другие. А, поскольку язык развивается, то какие-то пакеты и классы устаревают и не рекомендуются к использованию. Не удивляйтесь наличию примерно одинаковых классов, которые делают примерно одно и тоже. Если какой-то класс или пакет устарел, об этом обязательно укажут в документации.

Встроенные пакеты легко распознать по имени, они все начинаются со слова java. Но пакеты бывают и пользовательские. Фактически весь остальной код приложений и библиотек находится внутри своих пакетов. И мы снова приходим к проблеме конфликтов имен, но здесь уже не все так страшно. Пакетов значительно меньше чем классов и, как правило, они содержат какой-то префикс, который закреплен за конкретной компанией или продуктом. Например, пакеты организации Apache начинаются с org.apache, то есть это имя домена в обратном порядке. Повторить такое название технически можно, но никто не будет сам себе стрелять в ногу.

org.apache это пакет apache вложенный в пакет org. Как не трудно догадаться имя org может быть использовано разными компаниями, например org.w3c. Такая ситуация допустима, так как классы лежат дальше, уже внутри вложенных пакетов, которые точно уникальны.

// Класс генерирующий рандомные числа из пакета org.apache.commons.lang3 // Установку этого пакета в систему мы рассматриваем в другом курсе import org.apache.commons.lang3.RandomUtils; public class App  public static void main(String[] args)  var x = RandomUtils.nextInt(1, 1000); > > 

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

Определение пакетов

Структура пакетов связана со структурой директорий. Если пакет называется org.apache.commons.lang3, то путь к нему будет таким org/apache/commons/lang3. Имя пакета всегда соответствует директории, если пакет вложенный, то и директория тоже вложенная. В конце цепочки всегда файлы, в которых находятся классы. Их легко определить по названию, имена пакетов всегда идут с маленькой буквы, тогда как классов с заглавной. Пример создания пакета:

// io/hexlet/Course.java package io.hexlet; public class Course  // Тут логика > // com/google/App.java package com.google; import io.hexlet.Course; public class App  public static void main(String args[])  var course = new Course("Java"); > > 

Классы находящиеся в одном пакете видят друг друга без импортов:

// io/hexlet/Lesson.java package io.hexlet; public class Lesson  private Course course; // остальной код > 

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

Статический импорт

Java позволяет импортировать и использовать статические методы и свойства без указания самого класса:

import static java.lang.System.*; class App  public static void main(String args[])  // Можем опустить System out.println("GeeksforGeeks"); 

Открыть доступ

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

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов

Наши выпускники работают в компаниях:

Пакеты

Пакет является специальным библиотечным модулем, который содержит группу классов, объединённых в одном пространстве имён. Например, существует системная библиотека android.widget, в состав которой входит класс Button. Чтобы использовать класс в программе, можно привести его полное имя android.widget.Button. Но длинные имена классов не слишком удобно использовать в коде, поэтому можно использовать ключевое слово import.

import android.widget.Button;

Теперь к классу Button можно обращаться без указания полного имени.

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

Файл с исходным кодом на Java является компилируемым модулем. Имя модуля имеет расширение java, а внутри него может находиться открытый (public) класс с именем файла без расширения. Модуль может содержать один открытый класс, остальные классы не должны быть открытыми и считаются вспомогательными по отношению к главному открытому классу.

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

Указывать один и тот же пакет можно в разных файлах, он просто указывает кому принадлежит класс. Поэтому, если три разных класса в трёх разных файлах указывают на один и тот же package, то это нормально.

Можно создавать иерархию пакетов через точечный оператор:

package pack1[.pack2[.pack3]]; // например package cat.body.tail;

Создание уникальных имён пакетов

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

Доступ к членам класса

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

private Модификатор не указан protected public
В том же классе Да Да Да Да
Подкласс класса этого же пакета Нет Да Да Да
Класс из общего пакета, не являющийся подклассом Нет Да Да Да
Подкласс класса другого пакета Нет Нет Да Да
Класс другого пакета, не являющий подклассом класса данного пакета Нет Нет Нет Да

Любой компонент, объявленный как public, будет доступен из любого места. Компонент, объявленный как private, не виден для компонентов, расположенных вне его класса. Если модификатор явно не указан, он видим подклассам и другим классам в данном пакете. Это стандартное поведение по умолчанию. Если нужно, чтобы компонент был видим за пределами текущего пакета, но только классам, которые являются непосредственными подклассами данного класса, то используйте protected.

Это справедливо только для членов класса. У класса можно указать только два варианта: по умолчанию (не указан) и public.

Скорее всего в Android вам не придётся иметь дело с пакетами вплотную.

Импорт

В начале статьи я говорил вам, что импорт позволяет сократить написание полного имени класса. Он создан для удобства программистов и программа может обойтись из без него. Но если не выпендриваться и использовать импорт, то вы сократите уменьшите объём вводимого кода.

Оператор import должен идти сразу после оператора package (если он есть). Кстати, имя класса можно указать явно или с помощью символа «звёздочка» (*):

import java.io.*;

Но в Android такой способ категорически не рекомендуется использовать, так как ведёт к большому потреблению ресурсов. Да и сам я не разу не видел такой способ в примерах.

Таким образом, стандартный вариант:

 public class MainActivity extends Activity <> 

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

 public class MainActivity extends android.app.Activity <> 

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

В студии создать пакет можно двумя способами. Первый — традиционный, щёлкаем правой кнопкой мыши на папке java или на существующем пакете и выбираем в меню команду New | Package.

Второй способ более хитрый — когда вы создаёте в студии новый класс, то указывая его имя можете использовать точечную нотацию, например, database.CatDB. В этом случае пакет database будет создан автоматически и в нём будет находиться создаваемый класс.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *