Опирается на правила:
JS-5.1…JS-5.3из Java Style Guide → раздел 5. Отступы и форматирование.
Важно знать
- Длина строки ≤ 120 символов включая отступы.
- Перенос длинных — после запятой (для argument lists) или перед оператором (
+,&&).- Сопоставление новой строки с началом выражения — для multi-line.
- Не выравнивать переменные горизонтально — diff-noise при переименовании.
- 4 пробела для отступа (стандарт IntelliJ + checkstyle).
- No tabs — только spaces.
.editorconfigв репо обеспечивает консистентность между IDE/редакторами.
Форматирование — то, что не должно занимать времени на ревью. Один раз настроили IDE + Checkstyle + .editorconfig — дальше формат всегда правильный, никаких споров «куда поставить запятую».
Длина строки 120
JS-5.1: hard limit.
// ✓
private final OrderConfirmationService orderConfirmationService;
public List<OrderItemSummary> findItemsByCustomerAndStatusOrderedByDate(Long customerId, OrderStatus status) { ... }
// ^ 120
// ✗ — превышает 120
public List<OrderItemSummary> findItemsByCustomerAndStatusAndDateRangeOrderedByDate(Long customerId, OrderStatus status, Instant from, Instant to) { ... }
Почему 120 (не 80, не 100):
- 80 символов — конвенция времён punch cards. Современные мониторы 4К позволяют комфортно читать 120.
- 100 символов — middle-ground, но Java verbose names + generics часто упираются.
- 120 символов — sweet spot для современного Java. Split-screen на 4K возможен (2 файла по 120 = 240 + gutters).
При превышении — рефакторим:
- Длинное имя метода → возможно, делает слишком много.
- Длинная chain
.stream().filter(...).map(...).collect(...)→ multi-line. - Generic-сигнатура
Map<String, Map<Long, List<Order>>>→ typedef через record.
Перенос длинных выражений
JS-5.2: три паттерна.
После запятой — для argument lists
List<String> colors = Arrays.asList("red", "green", "blue");
// При переносе
List<String> colors = Arrays.asList(
"red",
"green",
"blue",
"yellow",
"orange"
);
Открывающая скобка — на той же строке. Закрывающая — на отдельной, выравнена с началом expression. Trailing comma в Java не поддерживается — последний элемент без ,.
Перед оператором — для арифметики/логики
// ✓ — оператор начинает следующую строку, видно что arithmetic
int sum = a
+ b
+ c;
boolean isValid = (count > 0)
&& (value != null)
&& (price.compareTo(BigDecimal.ZERO) > 0);
// ✗ — оператор в конце строки, читается хуже
int sum = a +
b +
c;
Оператор в начале новой строки сигналит «продолжение expression». Operator в конце предыдущей — легко пропустить при скане.
Сопоставление с началом
long totalCount = firstValue
+ secondValue
+ thirdValue
+ fourthValue;
String message = String.format(
"User: %s, Age: %d, Score: %f",
userName, userAge, userScore
);
Continuation aligned с началом expression — глаз сразу понимает «эти строки относятся к этой переменной».
Long method chains
// ✓
var orders = orderRepository.findAll()
.stream()
.filter(order -> order.status() == OrderStatus.CONFIRMED)
.map(OrderSummary::from)
.collect(Collectors.toList());
// ✗ — chain inline, long line
var orders = orderRepository.findAll().stream().filter(order -> order.status() == OrderStatus.CONFIRMED).map(OrderSummary::from).collect(Collectors.toList());
Каждый .method() — на новой строке с indent 4 пробела. Это делает chain читаемым «top to bottom».
Не выравнивать переменные
JS-5.3: запрет горизонтального выравнивания.
// ✗ — выравнено
public class Entity {
public String name;
public int age;
public Long createdBy;
public String description;
}
// ✓ — без выравнивания
public class Entity {
public String name;
public int age;
public Long createdBy;
public String description;
}
Почему не выравнивать:
- Refactoring noise. Переименовали
name→customerName— нужно переформатировать ВСЕ строки чтобы выравнивание сохранилось. Diff показывает 4 изменения вместо 1. - Авто-format ломает. IntelliJ auto-format не выравнивает (нет inspection), руками выравненный код потеряет alignment при reformat.
- Tabs vs spaces — выравнивание чувствительно к типу whitespace, в diff может выглядеть как rerun on different IDE settings.
Эта же логика для:
- Параметров метода в declarations.
- Field assignments в constructors.
- Map literals.
.editorconfig
Командные настройки в репо:
# .editorconfig
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.java]
indent_style = space
indent_size = 4
max_line_length = 120
[*.{yml,yaml}]
indent_size = 2
[*.md]
trim_trailing_whitespace = false
IntelliJ, VS Code, Vim — все читают .editorconfig. Каждый разработчик получает одинаковые настройки автоматически.
IntelliJ Code Style
Export командного code-style.xml + push в репо:
.idea/codeStyles/Project.xml # командный config
При open проекта IntelliJ предлагает использовать project code style. Никаких «у меня свой настроен дома».
Что запрещено
| Антипаттерн | Правило | Что взамен |
|---|---|---|
| Строка > 120 символов | JS-5.1 | перенос или refactoring |
| Горизонтальное выравнивание | JS-5.3 | без выравнивания |
| Tabs вместо spaces | conv | spaces |
indent_size: 2 для Java | conv | 4 для Java |
| Оператор в конце строки при переносе | JS-5.2 | оператор в начале |
Closing ) на той же строке что и последний arg | JS-5.2 | отдельная строка, выровнено с началом |
.method().method().method() inline 200 символов | JS-5.2 | one .method() per line |
| Different code style в разных файлах | conv | .editorconfig + IntelliJ project style |
Куда дальше
- Java → раздел 5. Отступы и форматирование — нормативные формулировки.
- Именование — длинные имена методов часто = длинные строки.
- Выражения — boolean complexity, method references.
- Checkstyle —
LineLength,Indentation. - Современные фичи Java — record и Java 21 features делают код короче.