Опирается на правила: JS-5.1JS-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;
}

Почему не выравнивать:

  1. Refactoring noise. Переименовали namecustomerName — нужно переформатировать ВСЕ строки чтобы выравнивание сохранилось. Diff показывает 4 изменения вместо 1.
  2. Авто-format ломает. IntelliJ auto-format не выравнивает (нет inspection), руками выравненный код потеряет alignment при reformat.
  3. 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 вместо spacesconvspaces
indent_size: 2 для Javaconv4 для Java
Оператор в конце строки при переносеJS-5.2оператор в начале
Closing ) на той же строке что и последний argJS-5.2отдельная строка, выровнено с началом
.method().method().method() inline 200 символовJS-5.2one .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 делают код короче.