Поиск…


Вступление

Официальное руководство Oracle по языку программирования Java является стандартом, за которым следуют разработчики Oracle, и рекомендуется следовать за любым другим разработчиком Java. Он охватывает имена файлов, организацию файлов, отступы, комментарии, декларации, заявления, пробелы, соглашения об именах, методы программирования и включает пример кода.

замечания

  • Приведенные выше примеры строго следуют новому официальному руководству по стилю от Oracle. Иными словами, это не субъективно составлено авторами этой страницы.

  • Официальное руководство стиля было тщательно написано, чтобы быть обратно совместимым с оригинальным руководством по стилю и большей частью кода в дикой природе.

  • Официальный стиль руководства был равный обзор в числе прочих, Брайан Гетц (Java Language архитектор) и Марк Рейнхольд (главный архитектор платформы Java).

  • Примеры не являются нормативными; Хотя они намереваются проиллюстрировать правильный способ форматирования кода, могут быть и другие способы правильного форматирования кода. Это общий принцип: может быть несколько способов форматирования кода, все придерживаясь официальных рекомендаций.

Соглашения об именах

Названия пакетов

  • Имена пакетов должны быть в нижнем регистре без символов подчеркивания или других специальных символов.
  • Имена пакетов начинаются с перевернутой части полномочий веб-адреса компании разработчика. За этой частью может следовать подструктура пакета, зависящая от структуры проекта / программы.
  • Не используйте множественную форму. Следуйте стандарту стандартного API, который использует, например, java.lang.annotation а не java.lang.annotations .
  • Примеры: com.yourcompany.widget.button , com.yourcompany.core.api

Имена классов, интерфейсов и имен

  • Имена классов и перечислений обычно должны быть существительными.
  • Имена интерфейсов обычно должны быть существительными или прилагательными, заканчивающимися ... способными.
  • Используйте смешанный регистр с первой буквой в каждом слове в верхнем регистре (например, CamelCase ).
  • Сопоставьте регулярное выражение ^[AZ][a-zA-Z0-9]*$ .
  • Используйте целые слова и избегайте использования сокращений, если аббревиатура более широко используется, чем длинная форма.
  • Отформатируйте аббревиатуру как слово, если оно является частью более длинного имени класса.
  • Примеры: ArrayList , BigInteger , ArrayIndexOutOfBoundsException , Iterable .

Имена методов

Имена методов обычно должны быть глаголами или другими описаниями действий

  • Они должны соответствовать регулярному выражению ^[az][a-zA-Z0-9]*$ .
  • Используйте смешанный футляр с первой буквой в нижнем регистре.
  • Примеры: toString , hashCode

переменные

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

  • Сопоставьте регулярное выражение ^[az][a-zA-Z0-9]*$
  • Дальнейшая рекомендация: Переменные
  • Примеры: elements , currentIndex

Переменные типа

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

  • Сопоставьте регулярное выражение ^[AZ][0-9]?$
  • Если одна буква более описательная, чем другая (например, K и V для ключей и значений на картах или R для возвращаемого типа функции), используйте это, в противном случае используйте T
  • Для сложных случаев, когда переменные однобуквенного типа запутываются, используйте более длинные имена, написанные всеми прописными буквами, и используйте подчеркивание ( _ ) для разделения слов.
  • Примеры: T , V , SRC_VERTEX

Константы

Константы ( static final поля, содержимое которых неизменно, по языковым правилам или по соглашению) должны быть названы всеми прописными буквами и подчеркиванием ( _ ) для разделения слов.

  • Сопоставьте регулярное выражение ^[AZ][A-Z0-9]*(_[A-Z0-9]+)*$
  • Примеры: BUFFER_SIZE , MAX_LEVEL

Другие рекомендации по именованию

  • Избегайте методов скрытия / теневого копирования, переменных и переменных типа во внешних областях.
  • Пусть многословность имени соотносится с размером области. (Например, используйте описательные имена для полей больших классов и краткие имена для локальных короткоживущих переменных).
  • При присвоении имен статическим членам, пусть идентификатор будет самоописательным, если вы считаете, что они будут статически импортированы.
  • Дальнейшее чтение: раздел именования (в официальном руководстве по стилю Java)

Источник: рекомендации стиля Java от Oracle

Исходные файлы Java

  • Все строки должны быть завершены символом линии (LF, ASCII значение 10), а не, например, CR или CR + LF.

  • В конце строки может отсутствовать конечное пробел.

  • Имя исходного файла должно совпадать с именем класса, которое оно содержит, за которым следует расширение .java , даже для файлов, которые содержат только закрытый класс пакета. Это не относится к файлам, которые не содержат объявлений классов, например package-info.java .

Специальные символы

  • Помимо LF единственным допустимым символом пробела является Space (значение ASCII 32). Обратите внимание, что это означает, что другие символы пробела (в, например, строковые и символьные литералы) должны быть записаны в экранированной форме.

  • \' , \" , \\ , \t , \b , \r , \f и \n должны быть предпочтительнее соответствующих восьмиугольных (например, \047 ) или Unicode (например, \u0027 ) экранированных символов.

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

Объявление пакета

package com.example.my.package;

Объявление пакета не должно быть обернуто линией, независимо от того, превышает ли она максимальную максимальную длину строки.

Импортные заявления

// First java/javax packages
import java.util.ArrayList;
import javax.tools.JavaCompiler;

// Then third party libraries
import com.fasterxml.jackson.annotation.JsonProperty;

// Then project imports
import com.example.my.package.ClassA;
import com.example.my.package.ClassB;

// Then static imports (in the same order as above)
import static java.util.stream.Collectors.toList;
  • Операторы импорта должны быть отсортированы ...

    • ... прежде всего нестатические / статические с нестационарным импортом.
    • ... вторично по происхождению пакета согласно следующему порядку
      • java-пакеты
      • пакеты javax
      • внешние пакеты (например, org.xml)
      • внутренние пакеты (например, com.sun)
    • ... третичный по идентификатору пакета и класса в лексикографическом порядке
  • Операторы импорта не должны быть обернуты линией, независимо от того, превышает ли она максимальную максимальную длину строки.

  • Не должно быть неиспользованного импорта.

Импорт подстановок

  • Импорт подстановочных знаков вообще не должен использоваться.
  • При импорте большого количества тесно связанных классов (например, внедрение посетителя над деревом с десятками различных классов «узлов») может использоваться импорт подстановочных знаков.
  • В любом случае следует использовать не более одного подстановочного импорта на файл.

Структура классов

Порядок учеников

Члены класса должны быть заказаны следующим образом:

  1. Поля (в порядке публичных, защищенных и частных)
  2. Конструкторы
  3. Фабричные методы
  4. Другие методы (в порядке публичных, защищенных и частных)

Приобретение полей и методов в основном с помощью их модификаторов доступа или идентификатора не требуется.

Вот пример этого порядка:

class Example {

    private int i;

    Example(int i) {
        this.i = i;
    }

    static Example getExample(int i) {
        return new Example(i);
    }

    @Override
    public String toString() {
        return "An example [" + i + "]";
    }

}

Группирование участников

  • Связанные поля должны быть сгруппированы вместе.
  • Вложенный тип может быть объявлен непосредственно перед его первым использованием; иначе он должен быть объявлен перед полями.
  • Конструкторы и перегруженные методы должны быть сгруппированы по функциональности и упорядочены с увеличением arity. Это означает, что делегирование между этими конструкциями идет вниз в коде.
  • Конструкторы должны быть сгруппированы вместе между другими членами.
  • Перегруженные варианты метода должны быть сгруппированы вместе между другими членами.

Модификаторы

class ExampleClass {
    // Access modifiers first (don't do for instance "static public")
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}

interface ExampleInterface {
    // Avoid 'public' and 'abstract' since they are implicit
    void sayHello();
}
  • Модификаторы должны идти в следующем порядке

    • Модификатор доступа ( public / private / protected )
    • abstract
    • static
    • final
    • transient
    • volatile
    • default
    • synchronized
    • native
    • strictfp
  • Модификаторы не должны выписываться, если они неявные. Например, методы интерфейса не должны быть объявлены public или abstract , а вложенные перечисления и интерфейсы не должны быть объявлены статическими.

  • Параметры метода и локальные переменные не должны объявляться final если они не улучшают читаемость или не документируют фактическое дизайнерское решение.

  • Поля должны быть объявлены final если нет веской причины сделать их изменчивыми.

вдавливание

  • Уровень отступов - четыре пробела .
  • Для отступов могут использоваться только пробелы. Нет вкладок.
  • Пустые строки не должны иметь отступ. (Это подразумевает правило без пробелов в пробеле).
  • строки case должны иметь отступы с четырьмя пробелами, а выражения в этом случае должны иметь отступы с четырьмя пробелами.
switch (var) {
    case TWO:
        setChoice("two");
        break;
    case THREE:
        setChoice("three");
        break;
    default:
        throw new IllegalArgumentException();
}

Обратитесь к инструкциям об обложке для рекомендаций относительно путей продолжения отступа.

Заявления об упаковке

  • Исходный код и комментарии обычно не должны превышать 80 символов в строке и редко, если когда-либо превышать 100 символов в строке, включая отступ.

    Предельный характер должен оцениваться в каждом конкретном случае. В действительности имеет значение семантическая «плотность» и читаемость строки. Создание линий безвозвратно долгим образом затрудняет их чтение; аналогичным образом, делая «героические попытки» поместить их в 80 столбцов, также может затруднить их чтение. Гибкость, изложенная здесь, направлена ​​на то, чтобы позволить разработчикам избежать этих крайностей, а не максимизировать использование монитора.

  • URL-адреса или примеры команд не должны быть обернуты.

// Ok even though it might exceed max line width when indented.
Error e = isTypeParam
        ? Errors.InvalidRepeatableAnnotationNotApplicable(targetContainerType, on)
        : Errors.InvalidRepeatableAnnotationNotApplicableInContext(targetContainerType));

// Wrapping preferable
String pretty = Stream.of(args)
                      .map(Argument::prettyPrint)
                      .collectors(joining(", "));

// Too strict interpretation of max line width. Readability suffers.
Error e = isTypeParam
        ? Errors.InvalidRepeatableAnnotationNotApplicable(
                targetContainerType, on)
        : Errors.InvalidRepeatableAnnotationNotApplicableInContext(
                targetContainerType);

// Should be wrapped even though it fits within the character limit
String pretty = Stream.of(args).map(Argument::prettyPrint).collectors(joining(", "));
  • Обертка на более высоком синтаксическом уровне предпочтительнее обертывания на более низком синтаксическом уровне.

  • В строке должно быть не более 1 строки.

  • Строка продолжения должна быть отступом одним из следующих четырех способов:

    • Вариант 1 : с 8 дополнительными пробелами относительно отступов предыдущей строки.
    • Вариант 2 : с 8 дополнительными пробелами относительно начального столбца обернутого выражения.
    • Вариант 3 : Согласовано с предыдущим выражением смежности (если ясно, что это линия продолжения)
    • Вариант 4 : Согласован с предыдущим вызовом метода в закодированном выражении.

Объявления об упаковке

int someMethod(String aString,
               List<Integer> aList,
               Map<String, String> aMap,
               int anInt,
               long aLong,
               Set<Number> aSet,
               double aDouble) {
    …
}

int someMethod(String aString, List<Integer> aList,
        Map<String, String> aMap, int anInt, long aLong,
        double aDouble, long aLong) {
    …
}

int someMethod(String aString,
               List<Map<Integer, StringBuffer>> aListOfMaps,
               Map<String, String> aMap)
        throws IllegalArgumentException {
    …
}

int someMethod(String aString, List<Integer> aList,
        Map<String, String> aMap, int anInt)
                throws IllegalArgumentException {
    …
}
  • Объявления метода могут быть отформатированы путем перечисления аргументов по вертикали или новой строки и +8 дополнительных пробелов
  • Если предложение throws необходимо обернуть, поставьте разрыв строки перед предложением throws и убедитесь, что он выделяется из списка аргументов, либо отступом +8 относительно объявления функции, либо +8 относительно предыдущей строки.

Условные выражения

  • Если линия приближается к максимальному пределу символа, всегда рассматривайте разбиение на несколько операторов / выражений вместо того, чтобы обертывать линию.
  • Перерыв перед операторами.
  • Перерыв перед. в цепных вызовах метода.
popupMsg("Inbox notification: You have "
        + newMsgs + " new messages");

// Don't! Looks like two arguments
popupMsg("Inbox notification: You have " +
         newMsgs + " new messages");

Пробелы

Вертикальные пробелы

  • Для разделения ...

    • Объявление пакета
    • Объявления классов
    • Конструкторы
    • методы
    • Статические инициализаторы
    • Инициализаторы экземпляра
  • ... и может использоваться для разделения логических групп

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

Горизонтальные пробелы

  • Необходимо использовать одно пространство ...

    • Чтобы отделить ключевые слова от соседних открывающих или закрывающих скобок и скобок
    • До и после всех двоичных операторов и операторов, таких как символы, такие как стрелки в лямбда-выражениях и двоеточие в расширенном для циклов (но не до двоеточия метки)
    • После // запускает комментарий.
    • После запятой разделяя аргументы и точки с запятой, разделяющие части цикла for.
    • После закрытия круглой скобки.
  • В объявлениях переменных не рекомендуется выравнивать типы и переменные.

Объявления переменных

  • Одна переменная для каждого объявления (и не более одного объявления в строке)
  • Квадратные скобки массивов должны быть в типе ( String[] args ), а не в переменной ( String args[] ).
  • Объявите локальную переменную прямо перед ее первым использованием и инициализируйте ее как можно ближе к объявлению.

Аннотации

Аннотации декларации должны быть помещены в отдельную строку из аннотации объявления.

@SuppressWarnings("unchecked")
public T[] toArray(T[] typeHolder) {
    ...
}

Тем не менее, несколько или короткие аннотации, аннотирующие однострочный метод, могут быть помещены в ту же строку, что и метод, если он улучшает читаемость. Например, можно написать:

@Nullable String getName() { return name; }

В целях согласованности и удобочитаемости все аннотации должны быть помещены в одну строку или каждая аннотация должна быть помещена в отдельную строку.

// Bad.
@Deprecated @SafeVarargs
@CustomAnnotation
public final Tuple<T> extend(T... elements) {
    ...
}

// Even worse.
@Deprecated @SafeVarargs
@CustomAnnotation public final Tuple<T> extend(T... elements) {
    ...
}

// Good.
@Deprecated
@SafeVarargs
@CustomAnnotation
public final Tuple<T> extend(T... elements) {
    ...
}

// Good.
@Deprecated @SafeVarargs @CustomAnnotation
public final Tuple<T> extend(T... elements) {
    ...
}

Лямбда-выражения

Runnable r = () -> System.out.println("Hello World");

Supplier<String> c = () -> "Hello World";

// Collection::contains is a simple unary method and its behavior is
// clear from the context. A method reference is preferred here.
appendFilter(goodStrings::contains);

// A lambda expression is easier to understand than just tempMap::put in this case
trackTemperature((time, temp) -> tempMap.put(time, temp));
  • Экспрессия lambdas предпочтительнее одноблочных блоков лямбда.
  • Ссылки на методы обычно должны быть предпочтительнее, чем лямбда-выражения.
  • Для ссылок на метод привязанных экземпляров или методов с arity больше единицы выражение лямбда может быть легче понять и, следовательно, предпочтительнее. Особенно, если поведение метода не ясно из контекста.
  • Типы параметров следует опустить, если они не улучшают читаемость.
  • Если выражение лямбда простирается более чем на несколько строк, подумайте о создании метода.

Резервные скобки

return flag ? "yes" : "no";

String cmp = (flag1 != flag2) ? "not equal" : "equal";

// Don't do this
return (flag ? "yes" : "no");
  • Резервные скобки для группировки (т.е. скобки, которые не влияют на оценку) могут использоваться, если они улучшают читаемость.
  • Резервные скобки для группировки обычно должны быть исключены из более коротких выражений, включающих общие операторы, но включаться в более длинные выражения или выражения, содержащие операторов, приоритет и ассоциативность которых неясны без круглых скобок. Тернарные выражения с нетривиальными условиями принадлежат последним.
  • Все выражения, следующие за ключевым словом return не должны быть окружены скобками.

литералы

long l = 5432L;
int i = 0x123 + 0xABC;
byte b = 0b1010;
float f1 = 1 / 5432f;
float f2 = 0.123e4f;
double d1 = 1 / 5432d;  // or 1 / 5432.0
double d2 = 0x1.3p2;
  • long литералы должны использовать суффикс буквы L верхнего регистра.
  • Шестнадцатеричные литералы должны использовать буквы верхнего регистра A - F
  • Все остальные числовые префиксы, инфиксы и суффиксы должны использовать строчные буквы.

фигурные скобки

class Example {
    void method(boolean error) {
        if (error) {
            Log.error("Error occurred!");
            System.out.println("Error!");
        } else { // Use braces since the other block uses braces.
            System.out.println("No error");
        }
    }
}
  • Открытие брекетов должно быть помещено в конец текущей строки, а не по отдельной линии.

  • Перед закрывающей скобкой должна появиться новая строка, если блок не пуст (см. Краткие формы ниже)

  • Скобки рекомендуются даже там, где язык делает их необязательными, например, однострочные и т. Д.

    • Если блок охватывает более одной строки (включая комментарии), он должен иметь фигурные скобки.
    • Если один из блоков в операторе if / else имеет фигурные скобки, другой блок тоже должен быть.
    • Если блок приходит последним в закрывающем блоке, он должен иметь фигурные скобки.
  • Ключевое слово else , catch и while do…while циклы идут по той же строке, что и закрывающая скобка предыдущего блока.

Краткие формы

enum Response { YES, NO, MAYBE }
public boolean isReference() { return true; }

Вышеуказанные рекомендации призваны улучшить единообразие (и, таким образом, повысить узнаваемость / удобочитаемость). В некоторых случаях «короткие формы», которые отличаются от приведенных выше рекомендаций, являются столь же читаемыми и могут использоваться вместо этого. К таким случаям относятся, например, простые перечисления enum и тривиальные методы и лямбда-выражения.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow