Java Language
Стандарт официального кода Oracle
Поиск…
Вступление
Официальное руководство 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)
- ... третичный по идентификатору пакета и класса в лексикографическом порядке
Операторы импорта не должны быть обернуты линией, независимо от того, превышает ли она максимальную максимальную длину строки.
Не должно быть неиспользованного импорта.
Импорт подстановок
- Импорт подстановочных знаков вообще не должен использоваться.
- При импорте большого количества тесно связанных классов (например, внедрение посетителя над деревом с десятками различных классов «узлов») может использоваться импорт подстановочных знаков.
- В любом случае следует использовать не более одного подстановочного импорта на файл.
Структура классов
Порядок учеников
Члены класса должны быть заказаны следующим образом:
- Поля (в порядке публичных, защищенных и частных)
- Конструкторы
- Фабричные методы
- Другие методы (в порядке публичных, защищенных и частных)
Приобретение полей и методов в основном с помощью их модификаторов доступа или идентификатора не требуется.
Вот пример этого порядка:
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 и тривиальные методы и лямбда-выражения.