Как правило, в Java классы объединяются в пакеты. Пакеты позволяют организовать классы логически в наборы. По умолчанию java уже имеет ряд встроенных пакетов, например, java.lang
, java.util
, java.io
и т.д. Кроме того, пакеты могут иметь вложенные пакеты.
Организация классов в виде пакетов позволяет избежать конфликта имен между классами. Ведь нередки ситуации, когда разработчики называют свои классы одинаковыми именами. Принадлежность к пакету позволяет гарантировать однозначность имен.
Чтобы указать, что класс принадлежит определенному пакету, надо использовать директиву package
, после которой указывается имя пакета:
1 2 3 4 5 6 7 8 |
package bookstore; public class BookStore { public static void main(String[] args) { } } |
В данном случае класс BookStore находится в пакете bookstore. При определении классов в пакеты на жестком диске эти классы должны размещаться в подкаталогах, путь к которым соответветствует названию пакета. Например, в данном случае файл BookStore.java будет находиться в каталоге bookstore.
Классы необязательно определять в пакеты. Если для класса пакет не определен, то считается, что данный класс находится в пакете по умолчанию, который не имеет имени.
Импорт пакетов и классов
Если нам надо использовать классы из других пакетов, то нам надо подключить эти пакеты и классы. Исключение составляют классы из пакета java.lang(например, String
), которые подключаются в программу автоматически.
Например, знакомый по прошлым темам класс Scanner
находится в пакете java.util, поэтому мы можем получить к нему доступ следующим способом:
1 |
java.util.Scanner in = new java.util.Scanner(System.in); |
То есть мы указываем полный путь к файлу в пакете при создании его объекта. Однако такое нагромождение имен пакетов не всегда удобно, и в качестве альтернативы мы можем импортировать пакеты и классы в проект с помощью директивы import, которая указывается после директивы package:
1 2 3 4 5 6 7 8 9 10 11 |
package bookstore; import java.util.Scanner; // импорт класса Scanner public class BookStore { public static void main(String[] args) { Scanner in = new Scanner(System.in); } } |
Директива import
указывается в самом начале кода, после чего идет имя подключаемого класса (в данном случае класса Scanner).
В примере выше мы подключили только один класс, однако пакет java.util
содержит еще множество классов. И чтобы не подключать по отдельности каждый класс, мы можем сразу подключить весь пакет:
1 |
import java.util.*; // импорт всех классов из пакета java.util |
Теперь мы можем использовать любой класс из пакета java.util.
Возможна ситуация, когда мы используем два класса с одним и тем же названием из двух разных пакетов, например, класс Date имеется и в пакете java.util, и в пакете java.sql. И если нам надо одновременно использовать два этих класса, то необходимо указывать полный путь к этим классам в пакете:
1 2 |
java.util.Date utilDate = new java.util.Date(); java.sql.Date sqlDate = new java.sql.Date(); |
Статический импорт
В java есть также особая форма импорта — статический импорт. Для этого вместе с директивой import
используется модификатор static
:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package bookstore; import static java.lang.System.*; import static java.lang.Math.*; public class BookStore { public static void main(String[] args) { double result = sqrt(20); out.println(result); } } |
Здесь происходит статический импорт классов System и Math. Эти классы имеют статические методы. Благодаря операции статического импорта мы можем использовать эти методы без названия класса. Например, писать не Math.sqrt(20)
, а sqrt(20)
, так как функция sqrt()
, которая возвращает квадратный корень числа, является статической. (Позже мы рассмотрим статические члены класса).
То же самое в отношении класса System: в нем определен статический объект out
, поэтому мы можем его использовать без указания класса.