Соглашения об именовании в Java
Практические правила именования пакетов, классов, методов, переменных и констант в Java.
Имена — самая дешёвая документация, которую вы когда-либо напишете, и самая дорогостоящая, если ошибитесь. В Java существует строгий, почти универсальный набор соглашений об именовании — закреплённый в оригинальной Java Language Specification и подкреплённый JDK, всеми крупными библиотеками и инструментами вроде Checkstyle. Следование им — это не вопрос вкуса: они позволяют любому Java-разработчику понять что это такое по способу написания, не читая ни одной строки тела. В этой главе собраны важнейшие правила именования и показаны в действии; по вопросам отступов, расстановки фигурных скобок и структуры файлов см. соглашения по оформлению кода Java.
Соглашения о регистре — кратко
Java назначает каждому виду идентификатора особый стиль написания. Регистр сам по себе говорит читателю о категории:
| Идентификатор | Соглашение | Пример |
|---|---|---|
| Пакет | только строчные, через точку, обратный домен | com.w3docs.billing |
| Класс / интерфейс / enum / record | PascalCase (UpperCamelCase), существительное | OrderLine, HttpClient |
| Метод | camelCase, глагольная фраза | calculateGrossTotal, isBulk |
| Переменная / параметр / поле | camelCase, существительное | taxRate, orderLines |
Константа (static final) | UPPER_SNAKE_CASE | MAX_RETRY_COUNT |
| Параметр типа | одна заглавная буква | E, T, K, V |
package com.w3docs.billing; // lowercase, reverse-domain
public class InvoiceService { // PascalCase class
private static final int MAX_RETRY_COUNT = 3; // UPPER_SNAKE_CASE constant
private final TaxTable taxTable; // camelCase field
public BigDecimal calculateTotal(List<LineItem> lineItems) { ... } // camelCase method
}Пакеты: строчные буквы и обратный домен
Имена пакетов всегда пишутся строчными буквами, без подчёркиваний, и начинаются с обратного домена, которым вы владеете — com.w3docs.billing, а не Billing или w3docs_billing. Префикс обратного домена делает пакеты глобально уникальными, чтобы они никогда не конфликтовали со сторонними библиотеками в classpath. Избегайте ключевых слов Java и цифр в начале любого сегмента. Смотрите раздел создание пакетов, чтобы узнать о структуре директорий, подразумеваемой этими именами.
package com.w3docs.billing.tax; // good: lowercase, reverse-domain, dotted
// package Com.W3docs.Billing; // bad: uppercase segments
// package com.w3docs.2024billing;// bad: segment starts with a digitКлассы — существительные, методы — глаголы
Класс, интерфейс, enum или record моделирует вещь, поэтому его имя — это именная фраза в PascalCase: Order, PaymentGateway, OrderLine. Метод что-то делает, поэтому его имя — глагольная фраза в camelCase: calculateTotal, sendInvoice, parseDate. Из этого вытекают два важных правила:
- Методы, возвращающие
boolean, читаются как вопрос:isEmpty,hasNext,canRetry. - Классические аксессоры используют префикс
get/set(getName,setName) — но Java records генерируют аксессоры, названные по имени поля без префикса (name(), а неgetName()).
interface PaymentGateway { // noun, PascalCase
boolean isAvailable(); // boolean → question form
Receipt charge(Money amount); // verb phrase
}
record Customer(String name, String email) { } // accessors: name(), email()Константы, переменные и параметры типа
Константа static final, значение которой фиксировано на этапе компиляции, использует UPPER_SNAKE_CASE, чтобы выделяться среди обычных переменных: MAX_RETRY_COUNT, DEFAULT_TAX_RATE. Локальные переменные, параметры и поля — это camelCase-существительные, описывающие значение, а не его тип — предпочитайте taxRate вместо d или theDouble. Обобщённые параметры типа — одиночные заглавные буквы по давно сложившемуся соглашению:
| Буква | Общепринятое значение |
|---|---|
E | Element (элемент коллекции) |
T | Type (общий тип) |
K, V | Key и Value (ключ и значение в словаре) |
R | Return type (возвращаемый тип) |
N | Number (число) |
static final double DEFAULT_TAX_RATE = 0.20; // constant
public <K, V> Map<K, V> copyOf(Map<K, V> source) { ... } // type params K, VТипичные ошибки
Некоторые антипаттерны встречаются снова и снова. Они компилируются, но мешают читателю:
- Венгерская нотация / кодирование типа в имени —
strName,iCount,lstOrders. Тип уже указан в объявлении; имя должно описывать смысл. - Однобуквенные локальные переменные вне счётчиков циклов —
c,x,tmpдля доменного значения скрывают намерение. - Загадочные сокращения —
calcGrsTtl. Пишите слова полностью; современные IDE автодополняют. l(строчная L) иOв качестве имён переменных — визуально неотличимы от1и0.- Имена классов в виде глаголов (
ProcessData) или имена методов в виде существительных — предпочитайтеorder.calculateTotal()для вычисляющего метода, оставляя форму чистого существительного чистым аксессорам.
Пример: все соглашения в одной программе
Эта программа объединяет все перечисленные выше правила в одном файле — константа, record с аксессорами без префикса, метод-вопрос boolean, camelCase-метод с описательными параметрами и обобщённый список. Читайте исходный код и вывод вместе, чтобы увидеть, как регистр соответствует категории.
Что следует вынести из запуска:
- Две константы
UPPER_SNAKE_CASEвыводятся какmax retry count : 3иdefault tax rate: 0.2— их регистр сигнализирует в месте использования, что это фиксированные общие значения, а не локальные переменные, которые можно переназначить. OrderLine— это PascalCase-record, и цикл читает его данные черезproductName(),quantity()иlineTotal()— обратите внимание, что нет префиксаget, поскольку аксессоры record называются точно по имени компонента.isBulk()выводитbulk=trueдля строки с 12 единицами иbulk=falseдля строки с 1 единицей: префиксisсообщал, что метод возвращает boolean, ещё до чтения его тела, и вывод подтверждает, что соглашение оправдывает себя в месте вызова.calculateGrossTotal— глагольный метод, параметры которогоorderLinesиtaxRateописывают смысл, а не тип — результатgross total : 111.60(93,00 нетто умноженное на 1,20) — именно то, что обещало имя метода.- Последняя строка использует
List<String>, обобщённый список с конкретным типом, отсылая к соглашению о параметрах типа (Eдля элемента), с которым объявлены коллекции JDK — программа выводит[alpha, beta], демонстрируя типизированный список в действии.