Правила форматирования кода в Java (ч. 5.1)

Введение

В предыдущей статье мы научились компилировать и запускать нашу программу, решая самые разнообразные проблемы, возникающие при этом.
Данная статья продолжает цикл публикаций для начинающих, и будет посвящена очень важной теме, которую многие игнорируют — теме правильного оформления кода в классе (его форматированию).

1. Форматирование кода

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

2. Для чего нужно форматирование

Открою вам секрет, что среднестатистический программист проводит гораздо больше времени за чтением кода, чем за его написанием. Читать код сложнее, чем писать, особенно чужой. Наличие общего стиля оформления программ облегчает понимание исходного кода, написанного разными программистами.
Стандарт оформления кода в каждой компании свой, но львиная его доля обычно одинакова, отличия не такие сильные. Когда, например, в рамках команды все пишут в одном стиле, а не кто как хочет, то это значительно облегчает восприятие кода, делает его понятнее и меньше грузит мозги программиста.
Давайте рассмотрим некоторые из правил оформления кода, которые были использованы при реализации класса MyFirstApp:
1
между ключевыми (зарезервированными языком Java) словами ставится один пробел, например, static void. Вам никогда не придется ставить два или более пробелов. И написать слитно, например, publicstatic по понятным причинам мы не можем, получится абракадабра, которая не заработает
2
после имени класса и перед { нужен пробел: MyFirstApp {
Это правило относится ко всем открывающимся фигурным скобкам, где бы они не стояли. А вот такой вариант уже выглядит небрежно: MyFirstApp{
3
метод main() размещается внутри класса, что говорит о его вложенности. Ее необходимо визуально как-то отображать. Для этого требуется сдвинуть метод целиком вправо на 4 пробела или на один Tab
4
код внутри метода, в свою очередь, вложен и в класс, и в метод main(). Значит, его нужно сдвинуть вправо на 4 пробела дважды: относительно начала класса и начала метода. Итого получается 8 пробелов от левого края редактора
5
после имени метода и перед ( пробел не ставится. Такой вариант будет неверным: main()
6
} должна размещаться строго под началом конструкции, к которой она принадлежит
Чтобы на первых порах вам было проще видеть, какой размер отступа используется в коде, ранее мы настроили Sublime Text на отображение пробелов в виде точек.
Чтобы было еще понятнее, начертим стрелки, показывающие направление сдвига кода относительно начала блока (вертикальных линий, которые отображает редактор).
Также необходимо понимать, что несоблюдение правил форматирования никак не влияет на запуск программы, т. к. они не важны для виртуальной машины. Они имеют значения для людей, читающих код.
Давайте напишем тот же самый код, но уже с ошибками форматирования, и попробуем его запустить.
Программа запустилась без каких-либо ошибок.

> java MyFirstApp.java
Написано однажды, работает везде
Можно записать весь код хоть в одну строку, но его никто не поймет. Многие начинающие разработчики не обращают внимание на внешний вид своего кода. Их цель — написать программу. Но есть хорошее выражение:
Любой дурак может написать код, понятный компьютеру. Хороший программист пишет код, понятный человеку
Мартин Фаулер

3. Правила форматирования Java-кода

В этом разделе собрано большое количество правил оформления кода, которые вы можете применять при написании своих программ на Java. Ранее мы уже публиковали (1, 2, 3) похожие правила от компании Google, но их отличие от представленных в этой статье в том, что они не такие детальные и подробные. Правила из этой статьи больше рассчитаны для начинающих программистов: они описывают каждую мелочь, каждую типичную ситуацию.
Применение данных техник сделает ваш код чистым, более читаемым и понятным. Не пренебрегайте ими! Будьте предельно внимательными.

3.1. Общие правила

1
Перед и после операторов =, +, -, /, *, %, ==, !=, <, <=, >, >= требуется пробел
неправильно:

System.out.println("дата="+m+"."+d+"."+y);
int length=5;
boolean isEqual = num1/10 == num2/10;
правильно:

System.out.println("дата = " + m + "." + d + "." + y);
int length = 5;
boolean isEqual = num1 / 10 == num2 / 10;
2
Между ){ скобками требуется пробел
неправильно:

- public Storage(){
- public static void main(String[] args){
- for (int i = 10; i > 0; i--){
- if (a > 10){
правильно:

- public Storage() {
- public static void main(String[] args) {
- for (int i = 10; i > 0; i--) {
- if (a > 10) {
3
После ( и перед ) скобками пробел не требуется
неправильно:

for ( int i = 0; i < 21; i++ )
compareNumbers( int number )
System.out.println( "Hello" )
if ( answer.equals("yes") )
правильно:

for (int i = 0; i < 21; i++)
compareNumbers(int number)
System.out.println("Hello")
if (answer.equals("yes"))
4
Код, вложенный в класс, метод, цикл и другие конструкции, которые имеют тело в виде { }, необходимо сдвигать вправо на 4 пробела (один Tab) относительно начала этой конструкции
неправильно:

public class Person {

    int age = 25;

    public static void main(String[] args) {
    if (age > 20) {
    System.out.println("Человек старше 20 лет");
    }
}
}
правильно:

public class Person {

    int age = 25;

    public static void main(String[] args) {
        if (age > 20) {
            System.out.println("Человек старше 20 лет");
        }
    }
}
5
При переносе строки каждую следующую ее подстроку необходимо смещать вправо на 8 пробелов относительно первой строки
неправильно:

System.out.println("Characteristics:\n" +
"age = " + age + "\n" +
"name = " + name + "\n" +
"color = " + color);
неправильно:

System.out.println("Characteristics:\n" +
                   "age = " + age + "\n" +
                   "name = " + name + "\n" +
                   "color = " + color);
правильно:

System.out.println("Characteristics:\n" +
        "age = " + age + "\n" +
        "name = " + name + "\n" +
        "color = " + color);
6
Для переноса курсора на новую строку, вместо System.out.println(); или System.out.println(""); используйте \n (где это возможно) — это уменьшит количество строк кода. Например:

System.out.println("\n2. Поиск максимального числа");
Если требуется больше переносов, то используйте нужное количество \n. Например:

System.out.println("\n\n1. Расчет стоимости\n\n");
7
В некоторых случаях использование \n не уместно. Вместо этого следует применить System.out.println()

Не используйте
System.out.print("\n");
или
System.out.printf("\n");
или
System.out.printf("%n"); 

вместо System.out.println();

Вместо
System.out.print("число\n");
или
System.out.print(number + "\n");

пишите System.out.println(number);
8
Не конкатенируйте \n отдельно от текста. Помещайте перенос в конец строки

Вместо:
System.out.println("Мама мыла раму" + '\n');

Пишите:
System.out.println("Мама мыла раму\n");
9
Размещайте комментарии над комментируемым кодом, а не справа от него. Комментарий должен начинаться с той же позиции, что и код
неправильно:

int sumOdd = 10; // сумма нечетных чисел
game.play(); // запуск игрового процесса
правильно:

// сумма нечетных чисел
int sumOdd = 10;

// запуск игрового процесса
game.play();
10
Отдавайте предпочтение использованию сокращенной формы записи арифметических операций
избыточно:

num1 = num1 - num2;
num1 = num1 ^ num2
правильно:

num1 -= num2;
num1 ^= num2

3.2. Правила для переменных

1
Давайте переменным осмысленные и понятные имена, глядя на которые, любому читающему код было бы ясно, какие значения они хранят
неправильно:

char a = '+';
int b = 10;
String с = "yes";
правильно:

char sign = '+';
int size = 10;
String answer = "yes";
2
Объявляйте переменные максимально близко к месту их первого использования, чтобы сузить область их действия. Не группируйте их в начале метода
3
В одной строке объявляйте не более одной переменной
неправильно:

int a, b, swap;
String name, letter;
правильно:

int a;
int b;
int swap;
String name
String letter;
4
Имя переменной не должно быть глаголом или содержать глагол
неправильно:

Resume createResume = storage.getResume(id);
правильно:

Resume resume = storage.getResume(id);
или
Resume newResume = storage.getResume(id);

5
Именуйте переменные, используя только английский язык
неправильно:

proizvedenie
procent
rezultat
правильно:

product (multiplication)
percent
result
6
Имена переменных начинайте с маленькой буквы
неправильно:

int Age;
int Title;
int FullName;
правильно:

int age;
int title;
int fullName;
7
Перед переменной при приведении типа требуется пробел
неправильно:

(char)i
правильно:

(char) i
8
Аббревиатуры в Java записываются как имена обычных переменных
неправильно:

int RAM;
long freqCPU;
String OS;
правильно:

int ram;
long freqCpu;
String os;
9
При использовании сокращенной формы инкремента и декремента, после имени переменной пробел не ставится
неправильно:

number ++
attempt --
правильно:

number++
attempt--
10
При именовании переменных для разделения слов нижнее подчеркивание _ ставится только у констант. Все остальные переменные должны именоваться с использованием camelCase
неправильно:

int hidden_number;
String player_answer;
правильно:

int hiddenNumber;
String playerAnswer;
11
Инициализируйте переменные (если это возможно) в строке их объявления, а не где-то ниже в коде
неправильно:

double num1;
char sign;
num1 = 4;
sign = '*';
правильно:

double num1 = 4;
char sign = '*';
12
Не придумывайте собственные сокращения для переменных. Нельзя просто взять и сократить имя так, как хочется. Программисту, читающему ваш код, их назначение будет сложно понять. А в больших программах возникнет целая проблема найти нужные переменные через поиск, т. к. никто не будет помнить, как именно были сокращены их имена. Можно использовать (и то аккуратно) только распространенные сокращения: tmp, num, nums, src, dest, hh, mm, ss, len и т. д.
неправильно:

double disc = 0.11;
int res = 100;
double pr;
правильно:

double discount = 0.11;
int result = 100;
double price = 17;
13
В рамках одной программы не используйте одновременно синонимы, сокращения и полные слова для именования переменных, которые хранят одни и те же по смыслу значения. Нельзя в одной строке написать имя целиком, где-то ниже полностью, а в другом классе использовать синоним. Все имена нужно именовать в одном стиле, используя одни и те же слова.
неправильно:

int reverseNumber;
int sumRevNum
int numb;
String invertString;
правильно:

int reverseNum;
int sumReverseNum;
int num;
String reverseString;

или

int reverseNumber;
int sumReverseNumber;
int number;
14
Не используете при именовании переменных абстрактные слова (без необходимости), которые ничего не означают, например, value, var, variable и т. д. Если переменная хранит число, то именуйте ее number или num. Это дает больше информации, чем value. Использование таких слов должно быть оправданным
15
Если вам требуется объявить однотипные по имени переменные, например, множество num, то проще писать num1, num2, numN, чем firstNum, secondNum или numFirst, numSecond. Что в первом варианте, что в остальных — смысл один и тот же, но первый вариант с numN — менее громоздкий и не такой многословный
16
Если имя переменной состоит из более, чем одного слова, то используется camelCase
неправильно:

int playeranswer
int counttwos;
String malegender
правильно:

int playerAnswer
int countTwos;
String maleGender
17
Имена boolean-переменных должны быть прилагательными
неправильно:

boolean security
boolean answer
boolean continue
правильно:

boolean active
boolean current
boolean alive

3.3. Правила для if-else

1
Между if и ( необходим пробел
допустимо:

if(a > b) {
    // some code
}
if(playerNum != secretNum) {
    // some code
}
правильно:

if (a > b) {
    // some code
}
if (playerNum != secretNum) {
    // some code
}
2
Даже если тело if-else состоит из одного выражения, всегда используйте { }. Это поможет избежать трудноуловимых багов
плохо:

if (doc.important)
    send(doc);
else
    System.out.println("Throw out the trash");
    delete(doc);
правильно:

if (doc.important) {
    send(doc);
} else {
    System.out.println("Throw out the trash");
    delete(doc);
}
3
Слово else и else-if оставляйте на той же строке, что и }, отделив их друг от друга пробелом
неправильно:

}
else {
    System.out.println("Exit");
}

}
else if (size < storage.length) {
правильно:

} else {
    System.out.println("Exit");
}

} else if (size < storage.length) {
4
Не отделяйте if от else новой строкой (где это возможно)
плохо (зачем тратить лишнюю строку под if):

} else {
    if (number > randomNumber) {
правильно:

} else if (number > randomNumber) {
5
Не оставляйте новый блок с if на одной строке с предыдущим if. Переносите его на следующую строку
неправильно:

if (num1 == num2) {
    // some code
} if (num3 == num4) {
    // some code
}
правильно:

if (num1 == num2) {
    // some code
}
if (num3 == num4) {
    // some code
}
6
При проверке boolean-значений не указывайте явно true или false
избыточно:

if (male == false) {

if (isExist(uuid) != true) {
правильно:

if (!male) {

if (!isExist(uuid)) {

3.4. Правила для циклов

1
Между for и (, между while и ( требуется пробел
допустимо:

for(int i = 0; i < 10; i++) {

for(int i = 10; i > 0; i--) {
    for(int j = 5; j > 0; j--) {
        // some code
    }
}

do {
    // some code
} while(true);

while(true) {
правильно:

for (int i = 0; i < 10; i++) {

for (int i = 10; i > 0; i--) {
    for (int j = 5; j > 0; j--) {
        // some code
    }
}

do {
    // some code
} while (true);

while (true) {
2
do-while оставляйте на той же строке, что и }, отделив их друг от друга пробелом
неправильно:

do {
    // some code
}
while ("yes".equals(answer));
правильно:

do {
    // some code
} while ("yes".equals(answer));
3
Стандартное именование счетчиков в цикле for — это i, j, k. Последние два используются для вложенных циклов
неправильно:

for (a = 0; a < 3; a++) {
правильно:

for (i = 0; i < 3; i++) {
неправильно:

for (d = 0; d < 10; d++) {
    for (c = 0; c < 4; c++) {    
        // some code
    }
}
правильно:

for (i = 0; i < 10; i++) {
    for (j = 0; j < 4; j++) {    
        // some code
    }
}
4
Имена переменных i, j, k допустимо использовать в качестве счетчика только для for. Для других циклов придумывайте более осмысленные имена
неправильно:

j = 5;
while (j > 1) {

i = 2;
do {
    // some code
} while (i > 0);
правильно:

row = 5;
while (row > 1) {

attempt = 3;
do {
    // some code
} while (attempt > 0);
5
В рамках одного метода, при использовании не вложенных циклов, не меняйте имена счетчиков
неправильно:

for (int i = 0; i < 10; i++) {

for (int j = 10; j > 0; j--) {

for (int k = 3; k > 0; k--) {
правильно:

for (int i = 0; i < 10; i++) {

for (int i = 10; i > 0; i--) {

for (int i = 3; i > 0; i--) {
6
Если тело цикла состоит из одного выражения, всегда используйте { }. Это поможет избежать трудноуловимых багов
неправильно:

while (number < 5)
    System.out.println("number less");
    number++;

for (int i = 0; i < 10; i++)
    System.out.print("Hello, ");
    System.out.println("Mike!");
правильно:

while (number < 5) {
    System.out.println("number less");
    number++;
}

for (int i = 0; i < 10; i++) {
    System.out.print("Hello, ");
    System.out.println("Mike!");
}
7
При проверке boolean-значений не указывайте явно true или false
избыточно:

while (isUnique() == true) {
правильно:

while (isUnique()) {
Автор: Чимаев Максим
Оцените статью, если она вам понравилась!