- Java Packages Tutorial
- What are packages
- How to manually create a package in Java
- How to create a package in Eclipse IDE
- How to import a package in Java
- Subpackages in Java
- Summary: Points to remember
- Пакеты классов, package
- Импорт пакетов и классов, import
- Статический импорт классов, import static
- Пример использования классов разных пакетов
- Листинг базового класса, BaseClass.java
- Листинг наследника, Inheritor.java
- Листинг основного класса, MainPackage.java
Java Packages Tutorial
In this Java tutorial we learn how to group related classes into packages to help control access and avoid naming conflicts.
We discuss how to manually create a package in Java or how to do it in an IDE like Eclipse. Then we look at how we can use the packages and subpackages.
What are packages
A package in Java is used to group related classes together. Packages help avoid naming conflicts, control access, makes searching program elements (classes, interfaces, enums and annotations) easier and helps us maintain our code.
We can think of packages as a folder in a directory where we store related class files. The folder then becomes a package that contains the class files inside, grouped together.
A package also creates a namespace automatically, which means if two classes have the same name, but are located in different packages, the names won’t conflict with each other.
There are two types of packages in Java:
How to manually create a package in Java
There are several options to create a new package in Java.
If you’re not using an IDE, you will need to execute the following command in the terminal.
javac -d package_folder file_name.java
The package_folder is the folder that all the related classes, interfaces, enums and annotations will be stored.
Inside the file_name.java file, we need to mark the package in the source code with the same name as the package_folder.
To mark a package, we use the package keyword, followed by the name, at the very top of a java document.
There can only be one package definition in each source file and it applies to all types in the file.
If we don’t define a package statement, all the types in the file will be placed in the ‘default’ package.
A popular naming convention, and considered good practice, is to name our packages in all lowercase, to avoid any conflicts.
In this tutorial course we’re using the Eclipse IDE, which makes it easy for us to create packages.
If you’re using a different IDE, like Netbeans or IntelliJ, please refer to their documentation for the steps to follow to create a new package.
How to create a package in Eclipse IDE
To create a new package in Eclipse, go to File > New > Package.
In the New Package window, it will ask us to specify the package location and name. The location should already be populated with the directory you’re currently working on.
For the name we’ll choose ‘demo’ and click on the Finish button to create the new package. Eclipse will automatically create the appropriate directory for us.
If we expand our project in the Project Explorer, we should see the new empty package.
The next step is to add classes to our package. Go to File > New > Class.
In the New Class window, select ‘demo’ as the Package, name the class ‘Logger’ and click on the Finish button to create the new class.
The class should open in the Code Editor window. It will have the package defined as ‘demo’ and the class defined as ‘Logger’.
Any class that we associate with the ‘demo’ package, will be stored in its directory.
How to import a package in Java
Before we import our new package into the main program, lets add some code to the class first.
In the ‘demo’ package, in the ‘Logger’ class, add the simple method below.
To import the package into our main program, we use the import keyword, followed by the package name. Then, with dot notation, we access the specific class we want to import.
If we need to, we can import all the classes in a package with the asterisk * wildcard operator.
The asterisk after the dot operator simply means: import all from package_name.
The whole ‘Logger’ class is now available to us to use as we normally would.
It’s good practice to separate each class in your program into a separate class file, and group related classes into packages. It keeps your code organized and easy to find.
Subpackages in Java
We can create packages within packages to separate and organize our classes even more.
For example, we could create a package called ‘vehicles’, with subpackages for cars, trucks and motorcycles.
Typically, a company uses its domain name in reverse for packages. For example, if the company domain name is ford.com , the packages would be: com\ford
So we would end up with a directory structure like:
com\ford\vehicle\car\mustang com\ford\vehicle\suv\everest com\ford\vehicle\commercial\ranger
which we would reference in our IDE as packages and import them with multiple levels of dot notation.
Java provides us with many useful packages to help create our applications. We import and use them in the same way as custom packages.
We will go through several packages throughout the rest of the tutorial course, when and where they’re needed.
You can also see a list of all the available packages for Java 13 or the Java 13 foundation packages from the official Java documentation.
Summary: Points to remember
- A package is similar to a folder in a directory, and groups related classes, interfaces, enums and annotations together.
- To associate a class with a package, we mark the top of the document with the package keyword and its name.
- To import a class from a package, we use the import keyword and the class name with dot notation, following the directory structure.
- To import all classes from a package we can replace the class name with an asterisk wildcard.
- Typically a reversed domain name is used as directory structure.
Пакеты классов, package
Пакет package позволяет логически объединить классы в наборы. Основные классы java входят в пакет java.lang. Различные вспомогательные классы располагаются в пакете в java.util. Классы для ввода и вывода входят в пакет java.io, а классы для работы в сети – в java.net. Некоторые их этих пакетов содержат подпакеты. Так, например, java.lang содержит два специализированных пакета java.lang.reflect и java.lang.ref, а java.util содержит подпакет java.util.zip, который включает классы для работы с ZIPархивами.
Каждый класс имеет как простое имя, данное ему в определении, так и полное имя, включающее имя пакета, в который он входит. Например, класс String является частью пакета java.lang, а его полное имя – java.lang.String.
Структура пакетов в точности отображает структуру файловой системы. Все файлы с исходными кодами (java-класс) и байт-кодами (расширением class), образующие один пакет, хранятся в одном каталоге файловой системы. Подпакеты образуют подкаталоги этого каталога. Каждый пакет создает единое пространство имен namespace. Это означает, что все имена классов и интерфейсов в пакете должны быть уникальны. Имена в разных пакетах могут совпадать, но это будут разные программные модули. Организация классов в виде пакетов позволяет избежать конфликта имен между классами. В пакете дублирование имен классов не допускается. Принадлежность класса к пакету позволяет гарантировать однозначность имен.
Чтобы указать, что класс принадлежит определенному пакету, следует использовать директиву package, после которой указывается наименование (путь) пакета :
package company.common; public class HelloWorld < public static void main(String[] args)< System.out.println ("Привет, мир!"); >>
В данном примере класс HelloWorld располагается в пакете company.common. Физически это директория «$/company/common». При создании класса в среде разработки IDE (например, Eclipse) следует указать наименование пакета, тогда IDE самостоятельно при необходимости создаст каталог на жестком диске и разместит новый класс в этом каталоге.
Можно package в классе не определять. В этом случае класс будет находиться в пакете по умолчанию, который не имеет имени «$», т.е. класс будет располагаться в корневой директории исходных кодов проекта.
Наименование пакета может быть любым, но необходимо соблюдать его уникальность в проекте. Соглашение «Code Conventions» рекомендует записывать имена пакетов строчными буквами. Тогда они не будут совпадать с именами классов, которые, по соглашению, начинаются с прописной буквы.
Стандартная библиотека Java API включает сотни классов. Каждый программист в ходе работы создает десятки своих классов. Множество классов быстро увеличивается. Java позволяет отдельные классы, решающие определенную задачу (или несколько задач), объединять в библиотеки классов в виде архивов jar. Но эти библиотеки классов, кроме стандартных, не являются частью языка java.
Импорт пакетов и классов, import
Для использования класса в приложении, его следует подключить. Так расположенный в пакете java.util класс Scanner можно подключить следующим способом :
java.util.Scanner in = new java.util.Scanner(System.in);
В этом примере при определении/создании нового объекта был указыван пакет (полный путь к файлу). Однако данный подход не всегда удобен, и в качестве альтернативы можно импортировать пакеты и классы в приложение с помощью директивы import, которая указывается после директивы package :
package company.common; import java.util.Scanner; public class HelloWorld < 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, или классам List пакетов java.util и java.awt. И если необходимо одновременно использовать оба эти класса, то необходимо указывать полный путь к классам в пакете :
java.util.Date udate = new java.util.Date(); java.sql.Date sdate = new java.sql.Date();
Следует сказать, что основные классы из пакета java.lang (например, String) подключаются автоматически и не требуют «импортирования».
Статический импорт классов, import static
В java можно использовать статический импорт. Для этого вместе с директивой import используется модификатор static :
package company.common; import static java.lang.Math.*; import static java.lang.System.*; public class HelloWorld < public static void main(String[] args) < double result = sqrt(20); out.println(result); >>
В примере определяется статический импорт классов System и Math, которые имеют статические методы. Определение статического импорта позволяет использовать статические методы без названия класса. В примере статическая функция sqrt(20) (можно и Math.sqrt(20)), возвращает квадратный корень числа. То же самое относится и к классу System, в котором определен статический объект out, поэтому можно его использовать без указания класса, если выполнен статический импорт класса System.
Пример использования классов разных пакетов
Рассмотрим простенький проект PackageExample, включающий 3 java-класса. Два java-класса располагаются в одном пакете «ru.java.online», а третий — в другом «ru.java.online.classes». Структура проекта представлена на следующем скриншоте:
Листинг базового класса, BaseClass.java
Базовый класс включает 2 поля (id, name) и методы get/set. В конструкторе значения полей инициализируется.
package ru.java.online; public class BaseClass < private String protected String name = null; public BaseClass() < this.id = "default"; this.name = "Наименование не определено"; >public String getId() < return id; >public void setId(String id) < this.id = id; >public String getName() < return name; >public void setName(String name) < this.name = name; >@Override public String toString() < return this.getClass().getName() + "\n\t"; > >
Переопределенная функция toString() возвращает наименование класса и значение полей.
Листинг наследника, Inheritor.java
Класс Inheritor.java наследует свойства базового класса BaseClass.java. Поскольку классы располаются в разных пакетах, то базовый класс необходимо импортировать.
package ru.java.online.classes; import ru.java.online.BaseClass; public class Inheritor extends BaseClass < public Inheritor() < this.name = "Наследник"; this.setId("Первый"); >>
Листинг основного класса, MainPackage.java
Основной класс включает статический метод main. Поскольку данный класс не «видит» наследника, то его приходится импортировать.
package ru.java.online; import ru.java.online.classes.Inheritor; public class MainPackage < public MainPackage() < BaseClass bc = new BaseClass(); Inheritor ir = new Inheritor(); System.out.println (bc.toString()); System.out.println (ir.toString()); >public static void main(String[] args) < new MainPackage(); System.exit(0); >>
Результат выполнения данной программы выводится в консоль в следующем виде :
ru.java.online.BaseClass: ru.java.online.classes.Inheritor:
Как видно по результату выполнения программы наименование класса включает пакет.
Говоря о полном наименовании класса следует отметить, что оно включает не только наименование пакета и наименование класса, но также и класс-загрузчик classloader. Подробно о классах-загрузчиках можно почитать здесь.