Google Java Style Guide 번역

최준영·2021년 10월 3일
0
post-custom-banner

1. Introduction

이 문서는 Java™ Programming Language의 소스 코드에 대한 구글의 코딩 표준의 완전한 정의 역할을 한다. Java 소스 파일은 여기서 규칙을 준수하는 경우에만 Google Style이라고 할 수 있다.

다른 프로그래밍 스타일 가이드와 마찬가지로, 다루는 내용은 포맷의 미학적 문제뿐만 아니라 다른 유형의 규약이나 코딩 표준도 포괄한다. 그러나, 이 문서는 주로 우리가 보편적으로 따르는 엄격하고 빠른 규칙에 초점을 맞추고 있으며, (인간에든 도구에 의해서든) 명확하게 실행할 수 없는 것에 대한 조언을 제공하지 않는다.

1.1 용어 참고 사항

다음 내용을 기본적으로 전제한다.

  1. 클래스라는 용어는 "일반적인" 클래스, 열거 클래스, 인터페이스 또는 어노테이션 유형을 의미하기 위해 포괄적으로 사용된다.(@interface).
  2. (클래스의)멤버라는 용어는 중첩된 클래스, 필드, 메서드 또는 생성자를 의미하기 위해 포괄적으로 사용된다. 즉, initializers와 주석을 제외한 클래스의 모든 최상위 수준의 내용을 의미한다.
  3. 코멘트라는 용어는 항상 구현 코멘트를 가리킨다. 우리는 "documentation comments"이라는 문구를 사용하지 않고, 대신 "Javadoc"이라는 통용어를 사용한다.
  • 다른 "단말기 노트"는 문서 전체에 가끔 나타날 것이다.

1.2 가이드 노트

이 문서의 예 코드는 비표준이다. 즉, 예제가 구글 스타일에 있지만, 코드를 표현하는 유일한 스타일리쉬한 방법을 설명하지는 못할 수 있다. 따라서 예제에서 사용된 형식들은 규칙으로 시행되지 않아야 한다.

2. 원본 파일 기본 사항

2.1 파일명

소스 파일 이름은 최상위 클래스의 클래스 이름을 포함하고 대소문자를 구분한 이름에 .java 확장자를 붙인다.

2.2 파일 인코딩: UTF-8

소스 파일은 UTF-8로 인코딩된다.

2.3 특수 문자

2.3.1 공백 문자

줄을 끝내는 문자를 제외하고, ASCII 수평 공백 문자(0x20)는 소스 파일의 어느 곳에서나 나타나는 유일한 공백 문자다. 이는 다음을 의미한다.

  1. 문자열과 character 리터럴의 다른 공백 문자는 모두 이스케이프된다.
  2. 탭 문자는 들여쓰기에 사용되지 않는다.

2.3.2 특수 escape sequences

8진수(예: \012) 또는 유니코드(예: \012)를 사용하는 대신, 특수 이스케이프 문자들(\b, \t, \n, \f, \r, \", \' \\)을 사용한다.

2.3.3 Non-ASCII 문자

나머지 Non-ASCII의 경우, 실제 유니코드 문자(예: ∞) 또는 동일한 유니코드 이스케이프(예: \u221e)를 사용한다. 유니코드가 문자열 리터럴 및 주석 외부에서 이스케이프하는 것은 권장하지 않지만, 가독성을 위해서는 상관없다.

팁: 유니코드 이스케이프 케이스에서 및 실제 유니코드 문자를 사용할 때에도, 설명하는 주석이 매우 유용할 수 있다.

예제

  • String unitAbbrev = "μs";
    • best: 주석 없이도 명확하다.
  • String unitAbbrev = "\u03bcs"; // "μs"
    • 허용되지만 이렇게 할 이유는 없다.
  • String unitAbbrev = "\u03bcs"; // Greek letter mu, "s"
    • 허용되지만 어색하고 실수하기 쉽다.
  • String unitAbbrev = "\u03bcs";
    • poor: 독자들은 이것이 무엇인지 전혀 모른다.
  • return '\ufeff' + content; // byte order mark
    • Good: 인쇄할 수 없는 문자의 경우 이스케이프를 사용하고, 필요한 경우 주석을 추가한다.

팁: 일부 프로그램이 Non-ASCII를 처리하지 못할 수 있다는 우려 때문에 가독성이 떨어지는 코딩을 하지 않는다.. 그런 경우에는 해당 프로그램이 중단과고 수정해야 한다.

3. 소스 파일 구조

원본 파일은 다음 순서로 구성된다.

  1. 라이센스 또는 저작권 정보(있는 경우)
  2. package 구문
  3. import 구문
  4. 하나의 최상위 클래스
    정확히 하나의 빈 줄이 각 섹션을 구분한다.

3.1 라이센스 또는 저작권 정보(있는 경우)

라이센스 또는 저작권 정보가 파일에 속할 경우 여기에 속한다.

3.2 package 구문

package 구문은 줄바꿈 하지 않는다. 열 제한 100은 패키지 문에는 적용하지 않는다.

3.3 import 구문

3.3.1 와일드카드 import 금지

static, 와일드카드 import는 사용하지 않는다.

3.3.2 줄바꿈 없음

import 구문은 줄바꿈하지 않는다. 열 제한 100은 적용하지 않는다.

3.3.3 순서 및 간격

import 구문은 다음과 같은 순서로 기입한다.

  1. 단일 블록에서 모든 static imports
  2. 단일 블록에서 모든 static imports
    static import, static import가 둘 다 있는 경우 하나의 빈 줄로 두 블록을 구분한다.

각 블록 내에서 import 구문은 ASCII 정렬 순서로 나타난다. (참고: 여기서 '.'가 ';'앞에 정렬되므로 ASCII 정렬 순서 인 import 문과 동일하지 않습니다 .)

3.3.4 클래스에는 static import를 하지 않는다.

static 중첩 클래스에는 static import가 사용되지 않는다. 일반적인 import로 사용한다.

3.4 클래스 선언

3.4.1 정확히 하나의 최상위 클래스 선언

소스 파일마다 각각의 최상위 클래스가 존재한다.

3.4.2 클래스 내용 순서

멤버들과 이니셜라이저들의 순서는 사용자가 코드를 이해하는데에 큰 영향을 줄 수 있다. 하지만 순서에 대해 정해진 방법은 없다. 각각의 클래스는 각자 다른 방법으로 내용의 순서가 정의될 것이다.

순서에 대해 정해진 방법은 없지만, 클래스는 각각의 논리적인 흐름으로 코드가 짜여진다. 단순히 새로운 메서드를 클래스의 끝에 추가하는 것이 아닌, 논리적인 흐름상 있어야 할 자리에 있어야 한다.

3.4.2.1 Overloads : 분리 X

클래스에 여러 개의 생성자 또는 이름이 같은 여러 개의 메서드가 있는 경우, 이러한 메서드는 중간에 다른 코드가 없는 상태로 순차적으로 나타난다.(private 멤버도 포함되지 않는다.)

4. Formatting

용어 참고
블록과 같은 구조(block-like construct)는 클래스, 메서드 또는 생성자의 본체를 가리킨다. 배열 이니셜라이저에 대한 섹션 4.8.3.1에 의해 배열 이니셜라이저는 선택적으로 블록과 같은 구조인 것처럼 취급될 수 있다.

4.1 중괄호(braces)

4.1.1 선택 사항인 경우 중괄호가 사용된다.

if, else, for, do-while 또는 구문이 없거나 한줄만 있는 경우에도 중괄호를 사용한다.

4.1.2 비어있지 않은 블록: K&R 스타일

브레이스는 비어 있지 않은 블록 및 블록 유사 구성물의 경우 Kernighan 및 Ritchie 스타일("Egyptian brackets")을 따른다.

  • 여는 중괄호 앞에 줄 바꿈이 없다.
  • 여는 중괄호 뒤에 줄 바꿈.
  • 닫는 중괄호 앞에 줄 바꿈.
  • 닫는 중괄호 뒤에 줄 바꿈 ( 중괄호가 명령문을 종료하거나 메서드, 생성자 또는 명명 된 클래스 의 본문을 종료하는 경우)
  • 중괄호 뒤에 else 또는 쉼표, 가 오면 줄 바꿈이 없다.

예제

return () -> {
  while (condition()) {
    method();
  }
};

return new MyClass() {
  @Override public void method() {
    if (condition()) {
      try {
        something();
      } catch (ProblemException e) {
        recover();
      }
    } else if (otherCondition()) {
      somethingElse();
    } else {
      lastThing();
    }
  }
};

Enum 클래스에 대한 몇가지 예외가 있는데, 4.8.1에서 다룬다.

4.1.3 빈 블록: 간결하게 해도 좋다.

빈 블록 또는 블록과 같은 구조는 K&R 스타일을 따를 수 있다.(4.1.2절 참조). 다른 방법으로, {}괄호 안에 문자가 없거나 단순 개행이라면 { 이후 바로 }가 올 수 있다. 하지만 if/else, try/catch/finally와 같이 다중 블록 명령문의 경우에는 { 이후 바로 }가 올 수 없다.

예제

  // 허용
  void doNothing() {}

  // 허용
  void doNothingElse() {
  }
  // 허용되지 않음 : 멀티 블럭 구문에서는 축약된 빈 블럭을 사용할 수 없다.
  try {
    doSomething();
  } catch (Exception e) {}

4.2 블록 들여쓰기(indentation): +2 공백

새 블록이나 블록과 같은 구조가 열릴 때마다 들여쓰기가 두 칸씩 늘어난다. 블록이 끝나면 들여쓰기는 이전 들여쓰기 수준으로 돌아온다. 들여쓰기 수준은 블록 전체의 코드와 주석 모두에 적용된다. (섹션 4.1.2 비어있지 않는 블록 참고)

4.3 한 줄에 한 문장씩

각 구문은 줄 바꿈을 한 번 한다.

4.4 열 제한: 100

자바 코드의 열 제한는 100자이다. "character"는 모든 유니코드 코드 를 의미한다. 아래에 명시된 경우를 제외하고, 이 제한를 초과하는 모든 라인은 제4.5절에서 설명한 대로 줄 바꿈을 해야 한다.

각 유니코드 코드 포인트는 길이와 상관없이 하나의 문자로 친다. 예를 들어,fullwidth characters를 사용할 경우 이 규칙보다 먼저 줄바꿈을 할 수 있다.

예외:

  1. 열 제한을 준수할 수 없는 라인(예: Javadoc의 긴 URL 또는 긴 JSNI 메서드 레퍼런스)
  2. package,import 문 (섹션 3.2 패키지 문 및 3.3 Import 문 참조 )
  3. 셸에 잘라서 붙여넣을 수 있는 Command line 주석

4.5 줄 바꿈(line-wrapping)

용어 참고
하나의 줄을 여러 줄로 나눌 때의 작업을 줄 바꿈이라고 한다.

모든 상황에 적용시킬 수 있는 형식은 없다. 여러가지 방법이 존재한다.

참고: 일반적으로 줄 바꿈을 하는 이유는 열 한도가 넘치지 않기 위해서지만, 실제로 열 한계에 맞는 코드도 저자의 재량에 따라 줄 바꿈을 할 수 있다.

팁: 메소드나 지역 변수를 추출하면 줄 바꿈 없이 문제를 해결할 수 있다.

4.5.1 줄 바꿈 위치

줄 바꿈의 주요 지침은 문법적으로 높은 레벨에서 줄 바꿈을 하는 것이다.

  1. 대입 연산자가 아닌 경우에서 줄 바꿈은 연산자 이전에서 줄 바꿈이 일어난다.(C++ 및 JavaScript와 같은 다른 언어의 경우 Google 스타일에 사용된 것과 다르다.)
  • 이는 다음과 같은 "operator-like" 기호에도 적용된다.
    • the dot separator(.)
    • the two colons of a method reference (::)
    • an ampersand in a type bound (<T extends Foo & Bar>)
    • a pipe in a catch block (catch (FooException | BarException e)).
  1. 대입 연산자의 경우에서는 일반적으로 연산자 이후에 줄 바꿈하지만, 이전에 해도 상관없다.
  • 이는 향상된 for문("foreach")의 "assignment operator-like" 콜론에도 적용된다.
  1. 메서드 또는 생성자 이름은 (를 붙여 쓰고 줄바꿈을 한다.
  2. 쉼표(,)는 붙여쓴다.
  3. lambda의 본문이 중괄호가 없는 단일 식으로 구성된 경우 화살표 바로 뒤에 줄 바꿈이 있을 수 있다. 이를 제외하고는 lambda의 화살표 바로 옆에서 줄이 끊어지지 않는다.

예제

MyLambda<String, Long, Object> lambda =
    (String label, Long value, Object obj) -> {
        ...
    };

Predicate<String> predicate = str ->
    longExpressionInvolving(str);

참고: 줄 바꿈의 주 목적은 가장 적은 수의 라인을 가지는 코드가 아닌 명확한 코드를 갖는 것이다.

4.5.2 연속 줄을 최소 +4칸 이상 들여쓰기

줄 바꿈을 할 때 첫 번째(각 연속 줄) 뒤의 각 줄은 원래 줄에서 적어도 +4 이상 들여쓰게 된다.

연속 줄이 여러 개일 경우, 원하는 대로 +4 이상으로 들여쓰기를 변경할 수 있다. 일반적으로 두 연속 줄은 구문 상 병렬 요소로 시작하는 경우에만 동일한 들여쓰기 수준을 사용한다.

수평 정렬의 섹션 4.6.3은 특정 토큰을 이전 라인과 정렬하기 위해 가변 공백 수를 사용하는 권장되지 않는 관행을 다룬다.

4.6 공백

4.6.1 세로 공백

다음의 상황에서는 항상 한줄 공백을 사용한다.

  1. 클래스의 연속적인 멤버 또는 initializers 간: 필드, 생성자, 메서드, 중첩 클래스, static initializers 및 인스턴스 initializer
  • 예외: 연속된 두 필드 사이의 빈 줄(그 사이에 다른 코드가 없음)은 선택 사항이다. 이러한 빈 줄은 필드의 논리적인 그룹화를 만드는 데 필요한 만큼 사용된다.
  • 예외: enum 상수 사이의 빈 줄은 섹션 4.8.1에서 다룬다.
  1. 본 문서의 다른 섹션(섹션 3, 소스 파일 구조 및 섹션 3.3, import 문 등)에서 요구하는 대로.

한 줄의 빈 줄은 가독성을 향상시키는 곳이라면 어디든 나타날 수 있다. 예를 들어, 코드를 논리적인 하위섹션으로 구성하기 위한 문장 사이에 말이다. 첫 번째 멤버 또는 이니셜라이저 앞, 또는 클래스의 마지막 멤버 또는 이니셜라이저 뒤에 빈 줄은 있어도 없어도 그만이다.

여러 개의 연속된 빈 줄은 허용되지만 필수는 아니다.

4.6.2 수평 공백

언어 또는 다른 스타일 규칙에서 요구하는 경우 외에 리터럴, 주석 및 Javadoc을 제외하고 ACII 공백은 다음의 경우에서만 사용한다.

  1. if, for 또는 catch와 같은 예약어와 여는 괄호 (()와 분리할 때
  2. 닫는 중괄호 (}) 다음에 오는 else, catch와 같은 예약어를 분리할 때
  3. 여는 중괄호 ({) 앞
  • 예외 1 : @SomeAnnotation({a, b}) (공백 사용 안 함)
  • 예외 2 : String[][] x = {{"foo"}}; ( 아래 항목 8에 따라, {{ 사이에 공백이 필요 없음)
  1. 이항 또는 삼항 연산자의 양쪽. 이는 다음과 같은 "operator-like" 기호에도 적용된다.
  • 타입 바인딩을 결합시키는 &: <T extends Foo & Bar>
  • 다중 예외를 처리하는 캐치 블록의 파이프: catch (FooException | BarException e)
  • 향상된 for문("foreach") 안의 콜론(:)
  • 람다 식의 화살표: (String str) -> str.length()
  • 다음의 경우에는 적용하지 않는다.
    • 메서드 레퍼런스의 두 콜론(::) : Object::toString
    • 다음과 같이 사용된 the dot separato(.) : object.toString()
  1. ,:; 뒤 또는 캐스팅의 닫는 괄호(')') 뒤
  2. 코드 뒤 주석을 달기 위해 오는 더블 슬래시 (//) 양쪽. 여러개의 공백이 허용되지만 필수는 아니다.
  3. 선언문의 타입과 변수 사이: List<String> list
  4. (필수 x) 배열 이니셜라이저의 괄호 안쪽.
    new int[] {5, 6}new int[] { 5, 6 } 둘 다 가능하다.
  5. type annotation과 [] 또는 ... 사이

이 규칙은 줄의 시작이나 끝에 추가 공간을 요구하거나 금지하는 것으로 해석되지 않으며, 내부 공간만 다룬다.

4.6.3 수평 정렬: 필수 x

용어 참고
수평 정렬은 특정 토큰이 이전 행의 특정 토큰 바로 아래에 나타나도록 하는 것을 목표로 코드에 공백을 추가하는 관행이다.

이 관행은 허용되지만 구글 스타일에서는 절대 요구되지 않는다. 이미 사용했던 장소에서는 수평 정렬을 유지할 필요도 없다.

예제

private int x; // this is fine
private Color color; // this too

private int   x;      // permitted, but future edits
private Color color;  // may leave it unaligned

팁: 정렬은 가독성을 도울 수 있지만, 향후 유지보수를 위해 문제를 일으킨다. 나중에 코드 한줄을 수정하는 경우, 이러한 변경으로 인해 이전에 완료되었던 포맷이 엉망이 될 수 있으며, 이는 허용된다. 더 자주 코더(아마도 여러분)에게 주변 라인의 공백을 조정하도록 유도하여 연쇄적인 리폼을 유발할 수 있다. 그 한 줄의 변화는 이제 "blast radius"을 갖게 되었다. 이것은 최악의 경우 무의미한 바쁜 일을 야기할 수 있지만 기껏해야 여전히 버전 이력 정보를 손상시키고 검토자의 속도를 늦추고 합병 충돌을 악화시킨다.

4.7 그룹화 괄호: 권장

선택적 그룹화 괄호는 작성자와 검토자가 없이, 코드가 잘못 해석될 가능성이 없으며 코드를 읽기 쉽게 만들지 않는다는 데 동의할 때만 생략된다. 모든 독자가 전체 자바 연산자 우선 순위표를 암기한다고 가정하는 것은 타당하지 않다. 사용하는 것이 좋다.

4.8 구체적인 구성

4.8.1 enum 클래스

열거형 상수를 따르는 각 쉼표 뒤에 줄 바꿈은 선택 사항이다. 추가 빈 줄(보통 한 줄만)도 허용된다.

예제

  private enum Answer {
  YES {
    @Override public String toString() {
      return "yes";
    }
  },

  NO,
  MAYBE
}

메소드와 문서가 없는 enum 클래스는 4.8.3.1의 배열 초기화와 같은 포멧을 가질 수 있다.

private enum Suit { CLUBS, HEARTS, SPADES, DIAMONDS }

열거형 클래스도 클래스이기 때문에 클래스 포멧팅 규칙이 적용된다.

4.8.2 변수 선언

4.8.2.1 선언당 하나의 변수

모든 변수 선언(필드 또는 로컬)은 다음과 같은 하나의 변수만 선언한다. int a, b; 방식은 사용되지 않는다.

예외: for문의 헤더 부분에서의 다중 변수 선언은 허용된다.

4.8.2.2 필요할 때 선언

지역 변수는 포함하는 블록이나 블록과 같은 구조의 시작에 습관적으로 선언되지 않는다. 지역 변수는 범위를 최소화하기 위해 처음 사용되는 지점에 가깝게 선언된다. 지역 변수 선언은 일반적으로 이니셜라이저가 있거나 선언 직후 초기화된다.

4.8.3 배열

4.8.3.1 배열 이니셜 라이저: "block-like"

배열 이니셜라이저는 선택적으로 블록과 같은 구조인 것처럼 포멧팅 될 수 있다.

예제 - 모두 가능

new int[] { 
  0, 1, 2, 3
}

new int[] { 
  0, 
  1, 
  2, 
  3,
}

new int[] { 
  0, 1, 
  2, 3
}

new int[] 
    {0, 1, 2, 3}

4.8.3.2 C 스타일로 배열 선언을 하지 않는다.

대괄호는 타입에 붙인다.

String[] args // ok
String args[] // no

4.8.4 Switch 구문

용어 참고
스위치 블록 의 중괄호 안에는 하나 이상의 구문 그룹이 있다.
각 구문 그룹은 하나 이상의 switch 라벨 (either case FOO: or default:)과 하나 이상의 명령문 (또는 마지막 명령문 그룹의 경우 0 개 이상의 명령문)으로 구성된다.

4.8.4.1 들여 쓰기

다른 블록들과 같이, 들여쓰기는 +2 space이다.
switch 라벨 이후, 줄 바꿈이 이루어지고, +2 만큼 들여쓰기가 되고, 블록이 오픈된 것 처럼 쓰인다.
이후의 switch라벨은 블록이 닫힌 것 처럼 이전의 들여쓰기 레벨과 같게 된다.

4.8.4.2 Fall-through: 주석

Switch 블록 내에서 break, continue, return, 예외 발생에 의해 구문을 종료하거나, 주석으로 실행될 것을 가리키거나, 다음 구문으로 넘어가게 할 수 있다.
fall-through를 할 수 있는 어떤 주석이든 상관없다.(보통 // fall through 사용)

예제

switch (input) {
  case 1:
  case 2:
    prepareOneOrTwo();
    // fall through
  case 3:
    handleOneTwoOrThree();
    break;
  default:
    handleLargeNumber(input);
}

case 1:다음에 주석이 필요하지 않으며, 명령문 그룹의 끝에서만 주석이 필요하다.

4.8.4.3 default 구문은 존재

switch 문에 default 코드가 없는 경우에도 default문을 포함시킨다.

예외: enum 유형에 대한 switch 문은 해당 유형이 가능한 모든 경우를 포함하도록 처리한 경우 생략 가능하다.
이를 통해 IDE 또는 기타 정적 분석 도구는 누락된 사례가 있을 경우 경고를 발생시킬 수 있다.

4.8.5 어노테이션

클래스, 메서드 또는 생성자에 적용되는 어노테이션은 documentation block 직후에 나타나며, 각 어노테이션은 한줄에 하나씩 쓴다. 이러한 줄 바꿈은 4.5절의 줄바꿈에 포함되지 않으므로 들여 쓰기 레벨이 증가하지 않는다.

예제

@Override
@Nullable
public String getNameIfPresent() { ... }

예외: 매개변수가 없는 단일 주석은 한 줄에 같이 쓸 수 있다.

@Override public int hashCode() { ... }

필드에 적용되는 어노테이션은 documentation block 직후에 나타나지만, 한줄로 나열할 수도 있다.

@Partial @Mock DataLoader loader;

매개변수, 지역 변수 또는 타입에 대한 어노테이션을 포멧팅하는 특정 규칙은 없다.

4.8.6 주석
이 절에서는 구현 주석을 다룬다. Javadoc은 7절 Javadoc에서 별도로 다룬다.

임의의 줄 바꿈은 임의의 공백 뒤에 구현 주석이 뒤따를 수 있다. 해당 주석 줄은 공백으로 간주되지 않는다.

4.8.6.1 블록 주석 스타일
블록 코드는 주변 코드와 동일한 수준으로 들여쓰기된다. 주석은 /* ... */ 스타일이나 // ... 스타일이 있다. 여러줄 주석(/* ... */)은 이전 줄의 * 위치에 정렬시켜야 한다.

/*
 * This is          // And so           /* Or you can
 * okay.            // is this.          * even do this. */
 */

주석은 별표나 다른 문자로 그려진 박스로 둘러쌓이지 않는다.

팁: 오토 코드 포멧터가 여러 줄의 주석을 re-wrap하는 것을 원한다면, /* ... */을 사용하라. 대부분의 포멧터는 // ... 주석은 re-wrap하지 않는다.

4.8.7 Modifiers (접근 제한자)

클래스 및 멤버 접근 제한자가 있을 경우 Java 언어 사양에서 권장하는 순서로 나열한다. 아래의 코드 순서로 작성하면 된다.

public protected private abstract default static final transient volatile synchronized native strictfp

4.8.8 숫자 리터럴

long타입 정수 리터럴에서 접미사를 붙일 때, 소문자가 아닌 대문자 L을 사용한다. 숫자 1과 혼동된다.
예를 들어, 3000000000l 보다는 3000000000L으로 사용한다.

5. Naming

5.1 모든 식별자에 적용되는 규칙

식별자는 ASCII 문자와 숫자만 사용하고, 아래에 명시된 몇몇 경우에는 밑줄(_)만 사용한다. 따라서 각 유효한 식별자 이름은 정규식과 일치한다. \w+

구글 스타일에서는 특수 접두사 또는 접미사가 사용되지 않는다. 예를 들어, 다음 이름은 Google Style이 아니다. name_, mName, s_name 그리고 kName.

5.2 식별자 유형별 규칙

5.2.1 패키지 이름

패키지 이름은 모두 소문자로, 연속된 단어는 밑줄 없이 그저 연결된다.

com.example.deepSpace // X
com.example.deep_space // X
com.example.deepspace // O

5.2.2 클래스 이름

클래스 이름은 UpperCamelCase로 작성된다.

클래스 이름은 일반적으로 명사 또는 명사 구절이다. 예를 들어, Character 또는 ImmutableList 인터페이스 이름은 보통 명사 또는 명사 구(예: List)로 짓지만, 형용사나 형용사 구(예: Readable) 짓는 경우도 있다.

어노테이션 유형의 작명에 대한 특정한 규칙이나 널리 퍼진 규칙이 없다.

테스트 클래스는 테스트 중인 클래스의 이름 뒤에 Test를 붙여준다. 예를 들어, HashTest 또는 HashIntegrationTest.

5.2.3 메서드
메서드 이름은 lowerCamelCase로 작성된다.

메서드 이름은 일반적으로 동사나 동사 구절이다. 예를 들어, sendMessage 또는 stop.

JUnit 테스트 메서드에서는 lowerCamelCase로 작성된 각 컴포넌트들을 논리적으로 구분하기 위해 _이 나타나는 경우가 있다.
pop_emptyStack.와 같이, 대표적인 패턴은 <methodUnderTest>_<state>이다. 테스트 메서드에서는 이름을 짓는 정해진 방법이 없다.

5.2.4 상수 이름

상수 이름은 CONSTANT_CASE처럼 짓는다. 대문자로 구성되며, 단어간에는 _로 구분한다.

상수는 값이 불변하고 메서드에 악영향을 주지않는, static final 필드이다. 여기에는 primitives, Strings, immutable types, and immutable collections of immutable types이 포함된다. 해당 인스턴스의 상태가 변할 수 있다면, 이는 상수가 아니다. 단지 객체 변형을 막는 것이 목적이 아니다.

예제

// Constants
static final int NUMBER = 5;
static final ImmutableList<String> NAMES = ImmutableList.of("Ed", "Ann");
static final ImmutableMap<String, Integer> AGES = ImmutableMap.of("Ed", 35, "Ann", 32);
static final Joiner COMMA_JOINER = Joiner.on(','); // because Joiner is immutable
static final SomeMutableType[] EMPTY_ARRAY = {};
enum SomeEnum { ENUM_CONSTANT }

// Not constants
static String nonFinal = "non-final";
final String nonStatic = "non-static";
static final Set<String> mutableCollection = new HashSet<String>();
static final ImmutableSet<SomeMutableType> mutableElements = ImmutableSet.of(mutable);
static final ImmutableMap<String, SomeMutableType> mutableValues =
    ImmutableMap.of("Ed", mutableInstance, "Ann", mutableInstance2);
static final Logger logger = Logger.getLogger(MyClass.getName());
static final String[] nonEmptyArray = {"these", "can", "change"};

이름은 일반적으로 명사나 명사구이다.

5.2.5 상수가 아닌 필드 이름

상수가 아닌 필드 이름(static 등등)은 lowerCamelCase로 기록된다.

이 이름들은 일반적으로 명사나 명사구절이다. 예를 들어, computedValues 또는 index.

5.2.6 매개변수(파라미터) 이름

매개변수 이름은 lowerCamelCase로 작성한다.

public 메소드에서 파라미터 이름을 한 문자로 작성하지 않는다.

5.2.7 지역 변수 이름

로컬 변수 이름은 lowerCamelCase로 작성된다.

final이나 불편인 경우에도 로컬 변수는 상수로 간주되지 않으며, 상수처럼 스타일링 하지 않는다.

5.2.8 타입 변수 이름

각 유형 변수는 다음 두 가지 스타일 중 하나로 명명된다.

  • 단일 대문자나 단일 대문자에 숫자 하나를 추가할 수 있다. (예: E, T, X, T2)
  • 5.2.2절의 방식으로 지어진 클래스 이름에 대문자 T를 추가한다.(예: RequestT, FooBarT).

5.3 Camel case: 정의

때때로 두음문자(예: FIFA, UN) 또는 "IPv6"나 "iOS"와 같은 특이한 영어 구문을 Camel case로 변환하는 합리적인 방법이 하나 이상 있다. 예측 가능성을 개선하기 위해 구글 스타일은 다음과 같은 결정론적 체계을 명시한다.

산문 형식으로 시작 :
1. 구문을 일반 ASCII로 변환하고 모든 아포스트로피(')를 제거한다. 예를 들어, "Müller's algorithm"를 "Muellers algorithm"로 변경한다.
2. 공백이나 나머지 문장 부호(일반적으로 하이픈)로 단어를 분할한다.

  • 권장: 원래 Camel case 단어인 경우, 구성 요소로 나눈다(예: "AdWords"는 "ad words"가 된다). "iOS"와 같은 단어는 Camel case가 아니다. 어떤 관습에도 어긋나기 때문에 이 권고사항은 적용되지 않는다.
  1. 모든 항목(두음문자어 포함)을 소문자로 표시한 후 다음을 따른다.
  • upper camel case로 표시
  • lower camel case로 표시
  1. 마지막으로 모든 단어를 단일 식별자로 결합한다.

원래 단어의 대소문자는 대부분 무시된다.

  • 가능하나 권장하지는 않음

참고: 영어의 몇몇 단어들은 모호하게 하이픈으로 되어 있다: 예를 들어 nonemptynon-empty은 둘다 맞다. 또한 메서드 이름 checkNonemptycheckNonEmpty도 둘다 맞다.

6. 프로그래밍 관행

6.1 @Override: 항상 사용

@Override 주석을 사용할 수 있는 경우 붙여준다. 여기에는 슈퍼클래스 방식을 오버라이딩하는 클래스 메서드, 인터페이스 메서드을 구현하는 클래스 메서드, super 인터페이스 방식을 오버라이딩하는 인터페이스 메서드가 포함된다.

예외: @Override 부모메서드가 @Deprecated(사용을 권장하지 않는다는 뜻)인 경우 생략할 수 있다.

6.2 Caught exceptions : 무시되지 않음
아래에 언급된 것을 제외하고, Caught exceptions에 대응을 아무것도 하지 않는 것은 매우 드물다. (일반적인 대응은 로그에 기록하거나, "불가능"으로 간주되는 경우, AssertionError로 rethrow한다.)

catch 블록에서 어떠한 조치도 취하지 않는 것이 적절하다면, 주석으로 설명한다.

try {
  int i = Integer.parseInt(response);
  return handleNumericResponse(i);
} catch (NumberFormatException ok) {
  // it's not numeric; that's fine, just continue
}
return handleTextResponse(response);

예외: 테스트에서 포착된 예외의 이름이 expected이거나 expected로 시작된다면, 주석을 무시할 수 있다. 테스트 중인 코드가 있다는 것을 보장해주는 일반적인 관용어이기 때문에 주석이 필요 없다.

try {
  emptyStack.pop();
  fail();
} catch (NoSuchElementException expected) {
}

6.3 Static members: 클래스명으로 호출

static class member를 호출하는 경우 클래스 변수 명이 아닌, 클래스 명을 사용한다.

Foo aFoo = ...;
Foo.aStaticMethod(); // good
aFoo.aStaticMethod(); // bad
somethingThatYieldsAFoo().aStaticMethod(); // very bad

6.4 Finalizers: 사용 X

Object.finalize를 오버라이드 하는 것은 매우 드물다.

팁: 사용하지 마라. 꼭 필요하더라도, Effective Java Item 7의 "Avoid Finalizers"를 주의깊게 읽어 보고 사용하지마라.

7. Javadoc

7.1 Formatting

7.1.1 일반 형식

Javadoc 블록의 기본 형식은 다음과 같다.

/**
 * Multiple lines of Javadoc text are written here,
 * wrapped normally...
 */
public int method(String p1) { ... }
  • 단일 행의 경우
/** An especially short bit of Javadoc. */

기본 형식은 항상 허용되며, Javadoc 블록 전체(주석 마커 포함)가 단일 라인에 들어갈 수 있는 경우에는 단일 라인 양식으로 사용할 수 있다. @return와 같은 블록 태그가 없을 때에만 사용할 수 있다.

7.1.2 문단

하나의 빈 줄(*만 존재하는 라인)은 문단 사이나 블록 태그 그룹(블록 태그가 있는 경우)전에 나타난다. 첫 번째 단락을 제외한 각 단락은 첫 번째 단어 앞에 <p>가 있고 그 뒤에 빈칸이 없다.

7.1.3 블록 태그

@param, @return, @throws, @deprecated의 순서대로 블록 태그를 사용하며, 빈 서술에 절대 사용하지 않는다.블록 태그가 한 줄에 들어가지 않는다면, 다음 줄은 @위치에서 +4 space 이상 들여쓰기를 한다.

7.2 The summary fragment

각각의 Javadoc은 간단한 summary fragment으로 시작한다. 이 summary fragment은 매우 중요하다. 클래스나 메서드 인덱스 같은 특정한 컨텍스트에서 나타나는 유일한 텍스트 부분이다.

이것은 fragment이다.

  • 완전한 문장이 아닌 명사구 또는 동사 구.
  • A {@code Foo} is a...또는 This method returns...로 시작하지 않는다.
  • Save the record..와 같은 완전한 명령문을 형성하지 않는다. Save the record..
    그러나 fragment은 완전한 문장인 것처럼 대문자로 표시되고 구두점을 가진다.

팁: 다음처럼 간단한 Javadoc을 작성할 때 실수가 잦다.

/** @return the customer ID */ X
/** Returns the customer ID. */ O

7.3 Javadoc이 사용되는 곳

보통 Javadoc은 모든 public 클래스, public클래스의 public 멤버와 protected멤버에서 쓰인다. 아래에 몇가지 예외 사항이 있다.

섹션 7.3.4, 비필수 자바독에서 설명한 추가 자바독 콘텐츠도 존재할 수 있다.

7.3.1 예외: self-explanatory 메서드

Javadoc은 getFoo와 같이 "단순하고 분명한" 이름의 메서드는 선택적으로 사용한다. getFoo는 Foo를 반환하라는 의미의 메서드인 것이 분명하다.

중요: 일반적인 독자가 알아야 할 관련 정보를 생략하는 것을 정당화하기 위해 이 예외를 인용하는 것은 적절하지 않다. 예를 들어, getCanonicalName 메서드의 경우 문서화를 생략하지 마라.(/** Return the canonical name. */ 주석을 추가하라). canonical name이 무슨 의미인지 모르는 사람이 있을 수 있다.

7.3.2 예외: 오버라이드(재정의)

Javadoc이 super 타입 방식을 오버라이드하는 메서드에 항상 존재하는 것은 아니다.

7.3.4 필수가 아닌 Javadoc

다른 클래스와 멤버는 필요하거나 원하는대로 Javadoc이 있다.

구현 주석이 클래스나 멤버의 전체적인 목적이나 기능을 정의한다면 주석은 Javadoc으로 대신한다. (/** 이용)

비필수 Javadoc은 섹션 7.1.2, 7.1.3 및 7.2의 포멧팅 규칙을 따르도록 권장하지만, 필수는 아니다.

profile
do for me
post-custom-banner

0개의 댓글