1. Пакеты

В стандартных Java-программах очень много классов. Сколько? Тысячи, десятки тысяч. А если еще посчитать, что программа использует различные библиотеки, которые содержат классы, написанные другими программистами, то количество классов легко может исчисляться миллионами!

Для всех этих миллионов, да и просто тысяч классов невозможно придумать уникальные имена.

Нет, ну конечно можно придумать имена типа А123, Б345, но если мы говорим о выборе для каждого класса хорошего имени, которое облегчает понимание этого класса (как String для строк, например), то даже тысяча уникальных имен — это большой труд.

Поэтому в Java все классы сгруппированы по пакетам.

Классы и их пакеты в Java по своей сути очень напоминают файлы и папки на компьютере.

Например, если вам нужно хранить на компьютере 10 документов, вы скорее всего просто будете хранить их в одной папке. А если документов тысячи (например, хранилище всех документов компании)?

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

Фактически в Java это все и было сделано для классов.

Файлы с классами хранятся в разных директориях (папках), и полное название папки класса со всеми подпапками называется пакетом класса. Пример:

Путь к файлу Имя пакета Имя класса
\com\javarush\tasks\Solution.java
com.javarush.tasks
Solution
\com\io\FileInputStream.java
com.io
FileInputStream
\java\util\ArrayList.java
java.util
ArrayList

Имя пакета, в отличие от имени папки, пишется через точку. Т.е. если папка была \com\javarush\tasks\, ей будет соответствовать пакет com.javarush.tasks.


2. Папка src

В Java принято все классы одной программы хранить в одной папке (и ее подпапках). Такую папку обычно называют src (сокращение от source).

Такая папка называется корнем проекта (source root), и все пути для пакетов считаются от нее. Примеры:

Папки Имя пакета
c:\projects\data\my\src\com\javarush\tasks\
com.javarush.tasks
d:\files\git\data\project\src\com\javarush\tasks\
com.javarush.tasks

Программисты в такой ситуации скажут что-то типа «у нас есть проект по имени my, который расположен в папке c:\projects\data» или «у нас есть проект по имени project, который расположен в папке d:\files\git\data»

Лучше всегда класть классы в пакеты, а не в корень папки src. Когда классов мало, это ещё не проблема, но когда классов много, очень легко запутаться. Поэтому всегда создавайте классы только в пакетах.

В Java принято давать классам и пакетам осмысленные имена. Многие компании выпускают свои библиотеки (набор классов) и, чтобы не было путаницы, называют пакеты этих классов по имени компании/сайта/проекта:

Имя пакета Имя компании/проекта
org.apache.common
org.apache.tomcat
org.apache.util
Проект «Apache»
com.oracle.jdbc
Компания «Oracle»
java.io
javax.servlet
Компания Oracle, проект Java
com.ibm.websphere
Компания «IBM», проект WebSphere
com.jboss
Проект «Jboss»

3. Содержимое файла

Согласно стандарту языка Java, внутри файла с кодом должна быть записана информация об имени класса и имя его пакета. Схема стандарта приведена ниже:

package имя-пакета;

public class Имя-класса
{

}

Имя пакета должно совпадать с именем папки, а имя файла — с именем публичного класса.

Если у вас есть файл ...\src\com\project\Service.java, значит у него внутри должно быть записано:

package com.project;

public class Service
{

}

4. Импорт классов

Имя класса + имя пакета формируют так называемое полное уникальное имя класса.

Примеры:

Полное уникальное имя Имя пакета Имя класса
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 добавили возможность «импортировать классы».

Вы можете использовать в своем коде короткое имя класса, но сначала вам нужно будет объяснить компилятору, какое именно «полное уникальное имя класса» соответствует короткому имени. Вдруг у вас в проекте несколько классов с таким именем. Или сначала был один, а потом еще 15 добавилось...

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

import полное-уникальное-имя-класса;

Добавлять такое объявление нужно в самом начале класса, сразу после объявления package.

Пример:

package com.javarush.tasks.task01;

import java.util.Scanner;
import com.test.helper.special.ArrayList;

public class Solution
{
   public static void main(String[] args)
   {
     Scanner console = new Scanner(System.in);
     ArrayList list = new ArrayList();
   }
}

Благодаря тому, что мы импортировали два класса java.util.Scanner и com.test.helper.special.ArrayList, мы можем использовать их короткие имена в нашем коде. И компилятор будет знать, какие именно классы использовать.

А вот как бы выглядел этот же код, если бы мы не использовали import:

package com.javarush.tasks.task01;

public class Solution
{
   public static void main(String[] args)
   {
     java.util.Scanner console = new java.util.Scanner(System.in);
     com.test.helper.special.ArrayList list = new com.test.helper.special.ArrayList();
   }
}

Кстати, если у вас в проекте есть два класса с именем Scanner, импортировать их оба в один файл с кодом не получится: для второго постоянно придется использовать длинное имя.

Допустим, у вас в коллективе есть Серега, и никаких проблем с общением, не возникает — все знают кто это. Но если бы их было трое, чтобы их различать, пришлось бы использовать полные уникальные имена.

Примечание 1

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

import имя-пакета.*;

Таким образом, вы сможете использовать в вашем коде короткие имена всех классов из данного пакета.

Примечание 2

Все классы из пакета java.lang импортируются автоматически, поэтому вам не нужно писать для них import. Один такой класс вы точно знаете: это класс... java.lang.String. Да, да, тот самый класс String, который используется для работы со строками.