Пакеты. Использование пакетов в Java. Директивы import и package. Компилированные модули (*.java). Промежуточные .class файлы. Структура проекта. Использование стандартных библиотек Java

Пакеты. Использование пакетов в Java. Директивы import и package. Компилированные модули (*.java). Промежуточные .class файлы. Структура проекта. Использование стандартных библиотек Java


Содержание



1. Пакеты в Java

Каждый проект на языке Java в своей работе использует так называемые пакеты. Пакет – это отдельный модуль (пространство имен), которому соответствует одноименный каталог (папка). Пакет содержит библиотеки (группы) классов. Эти классы объединены между собой в одном пространстве имен или пакете. Количество реализованных классов в пакете неограничено. Классы, которые объявляются в пакете, реализуются в файлах с расширением *.java.

Пакеты могут иметь разнообразные уровни вложения (подкаталоги, подпапки). На разных уровнях вложения пакетов имена могут повторяться. Сохранение пакетов и файлов *.java в проекте осуществляется в виде древовидной структуры файловой системы.

2. Как подключить пакет к существующему проекту в Java Eclipse? Структура проекта, который содержит пакеты

В системе Java Eclipse подключение пакета есть стандартной командой. Предварительно может быть создан проект. В проекте может размещаться произвольное количество пакетов. В каждом пакете может быть произвольное количество классов.

Для создания пакета в некотором проекте используется команда

File -> New -> Package

В результате откроется окно, изображенное на рисунке 1. В окне указывается имя проекта и пакета, который будет размещаться в этом проекте.

Рис. 1. Окно «New Java Package». Создание пакета с именем MyPackage в проекте MyProject03

После выбора кнопки Finish происходит следующее. Проекту с именем MyProject03 соответствует специальная папка (каталог) с таким же именем. В этом каталоге создается несколько подкаталогов (подпапок). Один из них подкаталог с именем src. В этом подкаталоге создается каталог MyPackage, соответствующий создаваемому пакету.

3. Какая общая форма вызова класса из пакета? Пример

Чтобы обратиться к имени класса из пакета используется следующая общая форма:

PackageName.ClassName

где

  • PackageName – имя пакета, в котором реализован класс с именем ClassName;
  • ClassName – имя класса.

Если пакет PackageName1 содержит подпапку (подпакет) с именем PackageName2, то доступ к классу с именем ClassName имеет вид:

PackageName1.PackageName2.ClassName

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

Например. Пусть задан пакет с именем Figures. В пакете реализованы два класса с именами Circle и Rectangle. Тогда, фрагмент кода, который создает объекты этих классов будет следующий:

// ...
Figures.Circle circle = new Figures.Circle();
Figures.Rectangle rect = new Figures.Rectangle();
// ...

4. Пример, который демонстрирует использование одного имени класса в разных пакетах и в разных каталогах (папках)

На рисунке 2 изображена иерархия, которую могут образовывать пакеты.

Рис. 2. В проекте MyProject03 три пакета с именами MyPackage01, MyPackage02, MyPackage02.MyFolder02

Как видно из рисунка, в проекте MyProject03 созданы 3 пакета с именами MyPackage01, MyPackage02, MyPackage03. Каждый из пакетов имеет класс с одинаковым именем MyClass01. Таким образом происходит разделение одинаковых имен.

Ниже приведен демонстрационный код, создающий объекты классов MyClass01, которые размещены в разных пакетах (папках), согласно схеме из рисунка 2.

// 1. Создается объект класса MyClass01 из пакета MyPackage01
MyPackage01.MyClass01 mc0101 = new MyPackage01.MyClass01();

// 2. Создается объект класса MyClass01 из пакета MyPackage02
MyPackage02.MyClass01 mc0201 = new MyPackage02.MyClass01();

// 3. Создается объект класса MyClass01 из пакета MyPackage02.MyFolder02
MyPackage02.MyFolder02.MyClass01 mc020201 = new MyPackage02.MyFolder02.MyClass01();

Как видно из программного кода, доступ к классу из пакета осуществляется с помощью разделителя ‘ . ‘ (точка). С целью сокращения весьма больших строк доступа к имени класса, используется директива import.

5. Какое назначение директивы import? Общая форма. Пример

Директива import позволяет сократить весьма длинные строки обращений к классам (интерфейсам, перечислениям), которые реализованы в пакетах.

В простейшем случае общая форма директивы import следующая:

import PackageName.ClassFileName;

где

  • PackageName – имя пакета, который подключается;
  • ClassFileName – имя файла с расширением *.java, в котором реализован класс или группа классов, к которому нужно обращаться по сокращенному имени.

Например. Пусть в некотором проекте задан пакет Figures. В пакете Figures реализован один класс с именем Circle. Класс размещен в файле «Circle.java». Исходный код файла Circle.java, который реализует класс Circle, имеет вид:

// файл "circle.java"
package Figures; // пакет Figures

// класс, который описывает окружность на координатной плоскости
public class Circle
{
    double radius;
    double x, y;

    // чтобы конструктор Circle() был видимым за пределами пакета,
    // должен быть установлен доступ public
    public Circle()
    {
        x = y = 0;
        radius = 1;
    }

    // спецификатор доступа public обязательный,
    // если нужно, чтобы метод Set() был видимым за пределами пакета
    public void Set(double x, double y, double radius)
    {
        this.x = x;
        this.y = y;
        this.radius = radius;
    }

    // метод, который возвращает площадь круга
    // перед методом используется спецификатор доступа public
    public double Area()
    {
        return 3.1415*radius*radius;
    }
}

Чтобы из любого другого класса, который размещается в другом пакете данного проекта, иметь доступ к методам файла Circle.java из пакета Figures нужно в начале указать:

import Figures.Circle;

Ниже приводится пример подключения и использования класса Circle из другого пакета и другого класса.

// файл "MyClass.java"
package OtherPackage;

// подключение класса Circle для сокращенного обращения
import Figures.Circle;

public class MyClass
{
    public static void main(String[] args)
    {
        // используется сокращенная форма обращения к имени класса
        Circle c = new Circle();
        double d;

        d = c.Area(); // d = 3.1415

        System.out.println("d = " + d);
    }
}

В вышеприведенном коде создается объект класса Circle с именем c. Однако, благодаря директиве import, название класса указывается в удобном (сокращенном) виде:

...

Circle c = new Circle();

...

Если в пакете OtherPackage убрать строку

import Figures.Circle;

то объект класса Circle нужно было бы создавать следующим образом

Figures.Circle c = new Figures.Circle();

6. Как в директиве import указать, что могут быть использованы все классы из данного пакета?

Бывают случаи, когда в пакете реализованы несколько классов (файлов с расширениями *.java) и возникает необходимость подключения всего множества классов. В этом случае общая форма директивы import может быть следующая:

import Package.*

где

  • Package – имя пакета с библиотекой подключаемых классов.

7. Что собой представляет ключевое слово package?

Ключевое слово package задает имя библиотеки, в которую могут входить разное количество компилированных модулей. Компилированные модули – это файлы с расширением .java.

Если в модуле (файле с расширением .java) указывается строка наподобие

package PackageName;

то это означает, что данный модуль есть частью библиотеки с именем PackageName.

8. Что такое компилированный модуль в Java?

Каждый компилированный модуль – это файл, который содержит исходный код на языке Java. Этот файл имеет расширение «*.java». Имя файла совпадает с именем открытого (public) класса, который реализован в этом модуле. Это требование есть обязательным.

Каждый компилированный модуль может содержать не большее одного открытого класса. Компилированный модуль входит в состав пакета. В пакете может быть любое количество компилированных модулей.

9. Какие требования к реализации компилированного модуля (.java)?

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

  • имя компилированного модуля должно иметь расширение .java;
  • имя компилированного модуля без учета расширения .java должно совпадать с именем открытого (public) класса, который реализован в этом модуле;
  • имя компилированного модуля и имя реализованного в нем открытого класса должны начинаться из большой буквы;
  • в компилированном модуле может быть не более одного открытого (public) класса. Если в компилированном модуле есть еще другие (вспомогательные) классы, то они должны быть скрытыми (без модификатора public).

10. Сколько классов могут быть реализованы в компилированном модуле?

Компилированный модуль может иметь любое количество классов. Однако, открытым (public) должен быть только один класс. Имя этого класса должно совпадать с именем компилированного модуля.

11. Какое назначение файлов с расширением .class?

Файлы с расширением .class получаются в результате компиляции файлов с расширением .java (компилированных модулей). Файлы с расширением .class есть промежуточными файлами, которые затем объединяются компоновщиком в исполнительный модуль.

Например, в языке программирования Delphi временные скомпилированные файлы имели расширение *.dcu. В языке программирования C++ временные скомпилированные файлы имели расширение .obj. После компоновки из этих файлов получался *.exe файл (исполняемый модуль).

После этого, файлы с расширением .class объединяются в пакет и сжимаются утилитой JAR. Это все осуществляет интерпретатор Java.

12. Какие преимущества дает использование ключевых слов package и import?

Использование ключевых слов package и import позволяет удобно поделить пространство имен таким образом, чтобы предотвратить возникновению конфликтов между разными разработчиками классов на Java.

13. Пример, который демонстрирует структуру проекта и размещение компилированных модулей

Пусть в Java Eclipse создан проект с именем Project03. Проект размещается в папке по умолчанию, которая используется системой Java Eclipse. В проекте созданы 2 пакета с именами Figures, OtherPackage. В пакетах реализованы по одному компилированному модулю соответственно с именами Circle.java и MyClass.java. Рисунок 3 отображает структуру проекта Project03 системы Java Eclipse.

Рис. 3. Отображение структуры проекта Project03 в окне Package Explorer

В файле (модуле) Circle.java разработан класс Circle. В файле MyClass.java разработан класс MyClass. В классе MyClass из пакета OtherPackage (см. рис. 3) подключается модуль Circle.java с помощью директивы

import Figures.Circle;

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

C:\Programs\Java + \Project03\src + \Figures\Circle.java

таким образом, получается полное имя модуля Circle.java:

C:\Programs\Java\Project03\src\Figures\Circle.java

По желанию путь к каталогу (папке) по умолчанию можно изменить.

14. Пример подключения класса из стандартной библиотеки Java

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

  1. Использование полной формы или полного имени класса в библиотеке.
  2. Использование сокращенной формы имени класса. В этом случае, полное имя пакета с нужным классом, может быть задано явным образом с помощью директивы import.

Полная форма обращения к имени нужного класса в простейшем случае выглядит так

java.PackageName.ClassName

где

  • PackageName – имя пакета или стандартной библиотеки Java (например, util, math, applet и прочее). Пакеты или библиотеки могут иметь уровни вложения. Если библиотеки содержат вложения, то они разделяются символом ‘ . ‘;
  • ClassName – имя класса (или интерфейса), который реализован в библиотеке PackageName (например ArrayList, BigDecimal и т.п.).

Например. Фрагмент кода, который использует класс Vector из стандартной библиотеки Java. В данном случае стандартная библиотека Java носит имя java.util.

...

// обращение к классу Vector из пакета java.util
java.util.Vector v = new java.util.Vector();

v.clear();
v.add("string - 01");
v.add("string - 02");
v.add("string - 03");

int n;
n = v.size(); // n = 3

String s;
s = (String)v.elementAt(0); // s = "string - 01"

В вышеприведенном коде происходит обращение к классу Vector по полному имени:

java.util.Vector


Связанные темы