Google Java Style Guide 한글 번역본 2023

neo-the-cow·2023년 2월 14일
0

2023년 2월 15일 작성

Google Java Style Guide 원문 링크

기존 검색 결과로 찾아 볼 수 있던 자료들에 누락, 변경, 어색한 부분이 있어 최신화했고 가능한 매끄럽게 읽힐 수 있게 정리했습니다.
오역이 있을 수 있으며 절대적으로 완벽한 자료가 아님을 알립니다.
오탈자나 오역 등 잘못된 부분이 발견될 경우 깃헙 이슈나 벨로그 댓글 등으로 알려주시면 즉시 반영하겠습니다.

1 소개

이 문서는 Java™️ 언어를 이용한 소스코드에 대한 Google 코딩 규칙의 완전한 정의를 제공합니다. Java™️ 소스 파일은 여기 있는 모든 규칙들은 준수 한 경우에만 Google 스타일로 설명됩니다.

다은 프로그래밍 스타일과 같이, 다루는 이슈들은 포매팅의 미적문제 뿐만 아니라 다른 유형의 컨벤션이나 코딩 규칙에도 적용 됩니다. 그러나 이 문서는 보편적으로 따르는 엄격한 규칙에 초점을 맞추고 있습니다. 그리고 (사람이나 도구 같은) 명확하게 강제 할 수 없는 조언을 제공하는것을 피합니다.

1.1 용어 참고

이 문서에서 특별이 명시하지 않는 한:

  1. 용어 class(클래스)는 "일반적인" 클래스나 열거형 클래스, 인터페이스, 어노테이션 유형(@interface)을 포괄적으로 의미하는데 사용됩니다.
  2. 클래스의 멤버는 중첩된 클래스나 필드, 메서드, 생성자 같은 이니셜라이저와 주석을 제외한 클래스의 모든 최상위 콘텐츠를 포괄적으로 의미합니다.
  3. Comment(주석)는 항상 구현 주석을 의미합니다. 우리는 documentation comments라는 용어를 사용하지 않고, 대신 Javadoc이라는 일반적인 용어를 사용합니다.

1.2 가이드 노트

이 문서상에 있는 예제코드는 표준이 아닙니다. 즉, 예제는 Google 스타일이지만 코드를 표현하는 유일하고 세련된 방법을 제공하지 못할 수 있습니다. 예제속에서 만들어진 선택적 형식 지정(Optional formatting choices)은 규칙으로 강제되면 안됩니다.

2 소스 파일 기본

2.1 파일명

소스 파일의 이름은 대소문자를 구분하는 최상위 클래스 이름(정확히 하나의 이름)과 .java확장자로 구성됩니다.

2.2 파일 인코딩 UTF-8

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

2.3 특수문자

2.3.1 공백문자

개행문자(원문상 'line terminator ') 시퀀스를 제외하고 ASCII horizontal space character (0x20)는 소스 파일 내부에서 나타나는 유일한 공백문자입니다. 이것은 다음을 나타냅니다.:

  1. 문자열과 문자 리터럴 내부의 다른 공백문자는 탈출 처리 됩니다.
  2. 탭 문자는 들여쓰기에 사용되지 않습니다.

2.3.2 특수한 탈출 시퀀스

특수한 탈출 시퀀스를 가진 문자들(\b\t, \n, \f, \r, \", \', \\)은 해당 진수(예. \012) 또는 유니코드(예. \u000a) 탈출 대신 해당 문자가 사용됩니다.

2.3.3 Non-ASCII 문자

아스키코드 외 나머지 문자의 경우, 실제 유니코드 문자(예. )또는 같은 유니코드 탈출(예. \u221e)이 사용됩니다. 코드를 더 쉽게 읽고 이해할 수 있는 방법에 따라 사용 할 수 있지만 유니코드가 문자열 리터럴이나 주석 외부에서 탈출하는것은 권장되지 않습니다.

: 유니코드 탈출 케이스나 실제 유니코드 문자가 사용되는 경우, 설명하는 주석이 매우 도움 될 수 있습니다.

예시:

ExampleDiscussion
String unitAbbrev = "μs";최고: 주석이 없지만 가장 명확합니다
String unitAbbrev = "\u03bcs"; // "μs"허용되지만, 이렇게 사용 할 이유가 없습니다.
String unitAbbrev = "\u03bcs"; // Greek letter mu, "s"허용되지만, 어색하고 실수하기 쉽습니다.
String unitAbbrev = "\u03bcs";나쁨: 이것이 무엇인지 알 수 없습니다.
return '\ufeff' + content; // byte order mark좋음: 출력할 수 없는 문자에는 탈출문자를 사용하고, 필요한 경우 주석을 사용합니다.

: 일부 프로그램이 Non-ASCII 문자를 제대로 처리하지 못할 수도 있다는 것 때문에 코드 가독성을 포기하지 마세요.
만약 그런 일이 발생한다면, 해당 프로그램들이 중단되고 수정되어야 합니다.

3 소스 파일 구조

소스 파일은 다음 순서로 구성됩니다.:

  1. 라이센스나 저장권 정보(있다면)
  2. 패키지 선언
  3. 임포트 구문들
  4. 정확히 하나의 최상위 클래스

정확히 하나의 빈 줄이 각 섹션을 구분합니다.

3.1 라이센스나 저장권 정보, 있는 경우

라이센스나 저장권 정보가 파일에 포함되어 있다면 여기에 해당합니다.

3.2 패키지 선언

패키지 선언은 줄 바꿈되지 않습니다. 패키지문에는 열 제한 (섹션 4.4 참고, 열 제한: 100)을 적용하지 않습니다.

3.3 임포트 구문들

3.3.1 와일드카드 임포트 금지

static 또는 기타 와일드 카드 임포트는 사용할 수 없습니다.

3.3.2 줄 바꿈 없음

임포트 구문들은 줄 바꿈되지 않습니다. 임포트 구문들에는 열 제한 (섹션 4.4 참고, 열 제한: 100)을 적용하지 않습니다.

3.3.3 정렬 및 간격

임포트 구문들은 다음과같이 정렬합니다.:

  1. 단일블록에서 모든 static 임포트 구문들.
  2. 단일블록의 모든 non-static 임포트 구문들.

만약 static 임포트와 non-static 임포트가 모두 존재한다면, 하나의 빈 줄이 두 블록을 구분합니다. 각 임포트문 사이에는 빈 줄이 없습니다.

각 블록내에서 임포트 한 이름은 ASCII 정렬 기준으로 정렬합니다.(참고: "."가 ";" 앞에 정렬되므로 ASCII 정렬 순서인 임포트 구문과 다릅니다.)

3.3.4 클래스 static 임포트 금지

static 중첩 클래스는 static 임포트가 사용되지 않습니다. 일반 임포트를 사용됩니다.

3.4 클래스 선언

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

소스파일별 각자 하나의 최상위 클래스를 가집니다.

3.4.2 클래스 내용 정렬 순서

클래스 멤버나 이니셜라이저의 정렬 순서는 이해하는데 큰 영향을 미칩니다. 그러나, 명확히 정해진 방법은 없습니다. 다른 클래스는 다른 방식으로 내용의 순서를 정할 수 있습니다.

중요한것은 각 클래스가 몇가지 관리자가 요청하면 설명 할 수 있어야 하는 논리적 순서를 사용하는것 입니다. 예를들면, 새 메서드가 습관적으로 클래스 끝에 추가되었다면 이는 "추가된 순서순" 정렬일 뿐 논리적 순서가 아닙니다.

3.4.2.1 오버로드: 절대 분할 하지 말것

클래스 내부에 같은 이름을 가진 메서드가 여러개 있는 경우 이들 사이에 다른 코드 순서대로 나타내야 합니다. 이는 여러개의 생성자가 있는 경우(같은 이름을 가진)도 해당됩니다. 이 규칙은 static 이나 private 같은 접근제한자가 메서드별로 다른 경우에도 적용됩니다.

4 포매팅

용어 참고: block-like 구조는 클래스또는 메서드, 생성자의 본문을 나타냅니다. 배열 초기화의 섹션 4.8.3.1에 따라 모든 배열 초기화는 선택적으로 block-like 구조로 처리될 수 있습니다.

4.1 괄호

4.1.1 선택사항인 경우에도 중괄호 사용

괄호는 ifelse, for, do, while문의 내용이 비어있거나 하나의 문장이 있는 경우에도 사용됩니다.

람다표현 같은 다른 선택적 괄호는 해당되지 않습니다.

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

비어있지 않거나 block-like 구조에서 괄호는 Kernighan & Ritchie 스타일("이집트 대괄호")을 따릅니다.:

  • 아래 자세히 설명된 경우를 제외하고, 여는 괄호 앞에는 줄바꿈이 없습니다.
  • 여는 괄호 뒤에서 줄을 바꿉니다.
  • 닫는 괄호 앞에서 줄을 바꿉니다.
  • 닫는 괄호 뒤에서는 닫는 괄호가 문장을 끝내는 경우나 메소드나 생성자, 명명된 클래스의 본문을 종료하는 경우에만 줄을 바꿉니다. 예를 들어, 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();
        }
        {
            int x = foo();
           frob(x);
        }
    }
};

열거형 클래스들에 대한 몇가지 예외조항들은 섹션 4.8.1, 열거형 클래스에 나와 있습니다.

4.1.3 빈 블록들: 간결할 수 있음

빈 블록이나 block-like 구조는 K & R 스타일(섹션 4.1.2에 설명됐듯)을 적용할 수 있습니다. 아니면, 다중 불록 문장(여러 블록을 직접 포함하는 블록: if/elsetry/catch/finally)의 일부가 아닌 한 괄호({})사이에 문자나 줄바꿈 없이 닫을 수 있습니다.

예시:

    // 허용 될 수 있습니다.
    void doNothing() {}

    // 또한 허용 될 수 있습니다.
    void doNothingElse() {
    }
    // 허용되지 않습니다.: 멀티블록 구문에서는 간결한 빈 블록을 사용할 수 없습니다.
    try {
        doSomething();
    } catch (Exception e) {}

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

새로운 블록이나 block-like 구조가 열릴 때 마다, 들여쓰기가 두 칸씩 증가합니다. 블록이 끝날 때, 들여쓰기는 이전 들여쓰기 레벨로 돌아갑니다. 들여쓰기 레벨은 블록 전체의 코드와 주석 모두에 적용됩니다. (비어있지 않은 블록: K & R 스타일, 섹션 4.1.2 를 참조하세요.)

4.3 한줄에 하나의 문장

각 문장 뒤에는 줄바꿈이 따라옵니다.

4.4 열 제한: 100

자바코드는 100자로 열을 제한됩니다. 하나의 "문자"는 모든 유니코드 포인트를 뜻합니다. 아래 언급한 것을 제외하고 이 제한을 초과한 모든 라인은 반드시 섹션 4.5, 줄 바꿈에 대한 설명대로 줄 바꿈 되어야 합니다.

각 유니코드 포인트들은 출력되는 너비가 넓거나 좁아도 하나의 문자로 계산됩니다. 예를 들어, 전체 너비 문자를 사용하는 경우 이 규칙이 강제되는 위치보다 먼저 줄바꿈을 선택할 수 있습니다.

예외:
1. 열제한을 따를 수 없는 라인들은 규칙 적용이 불가능 합니다. (예를 들어, Javadoc 의 긴 URL 이나 긴 JSNI 메서드 참조)
2. 패키지선언과 임포트문장. (섹션 3.2 패키지 선언과 섹션 3.3 임포트문을 참조하세요.)
3. 셸에 복붙되는 주석의 명령 라인.
4. 드물게 요구되는 경우 아주 긴 식별자도 열제한을 초과할 수 있게 허용됩니다. 이 때, 유효한 줄 바꿈은 구글-자바-형식으로 생성됩니다.

4.5 줄 바꿈

용어 참고: 한 줄을 문제없이 점유할 수 있는 코드가 하나의 줄에서 여러줄로 나뉠 때, 이 작업을 줄 바꿈이라고 합니다.

모든 상황에서 줄바꿈을 정확하게 나타내는 포괄적이고 결정적인 공식은 없습니다. 매우 자주 같은 코드 조각을 줄바꿈 하는 몇가지 방법이 있습니다.

참고: 줄 바꿈의 대표적인 이유가 열 제한을 초과하지 않기 위함이기 때문에, 실제로 열 제한을 준수하는 코드 또한 작성자의 재량에 따라 줄 바꿈이 가능합니다.

: 메서드 분리나 지역변수가 줄 바꿈 없이 이 문제를 해결 할 수 있습니다.

4.5.1 어디서 줄을 바꾸나요?

줄바꿈의 주요 지침은 다음과 같습니다: 더 높은 구문 레벨에서 바꿉니다. 또한:

  1. 한 줄이 비 할당 연산자에서 바뀔 때, 기호 앞에서 바뀝니다. (C++ 이나 Javascript 와 같은 다른 언어의 Google 스타일에서 적용되는 것과 다르단 것을 알립니다.)
    • 또한 이것은 다음 "operator-like" 기호들에도 적용됩니다.
      • 점 구분 기호(.)
      • 메서드 참조의 두 콜론(::)
      • 타입 바운드의 앰퍼센드(<T extends Foo & Bar>)
      • catch 블록의 파이프(catch (FooException | BarException e))
  2. 할당 연산자에서 줄이 바뀔 때, 줄바꿈은 일반적으로 기호 뒤에 오지만, 어느쪽이든 허용됩니다.
    • 이것은 향상된 for ("foreach")문의 "assignment-operator-like"한 콜론에도 적용됩니다.
  3. 메서드나 생성자 이름은 그 뒤에 오는 여는 괄호와 붙어있습니다.
  4. 쉼표(,)는 앞에 오는 토큰에 계속 붙어있습니다.
  5. 람다에서 본문의 괄호가 없는 단일 표현식으로 구성될 경우를 제외하고, 화살표와 인접한 줄은 절대 바뀌지 않습니다. 예시:
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. 연속적인 멤버나 클래스 초기화 사이: 필드나 생성자, 메서드, 중첩 클래스, 정적 초기화 객체 초기화
  • 예외: 두개의 연속된 필드 사이(사이에 아무런 다른 코드가 없을 때) 빈 줄은 선택적입니다. 이러한 빈 줄은 논리적 그룹을 만들어야 할 때 사용됩니다.
  • 예외: 열거영 상수 사이 빈 줄은 섹션 4.8.1에서 다룹니다.
  1. 이 문서의 다른 섹션이 요구하는 바와 같습니다 (예시: 섹션 3 소스 파일 구조, 섹션 3.3 임포트 구문).

또한 빈 줄은 가독성을 높이는 모든 위치에서 나타날 수 있습니다, 예를 들어 논리적 하위섹션으로 구성되는 명령문 사이. 첫번째 멤버나 이니셜라이저 앞의 빈 줄이나, 마지막 멤버나 이니셜라이저 뒤의 빈 줄은 권장되지 않지만 금지되지도 않습니다.

여러개의 연속적인 빈 줄은 허용됩니다만, 절대 필수(또는 권장)는 아닙니다.

4.6.2 가로 공백

리터럴과 주석, Javadoc 을 제외하고 언어나 다른 스타일 규칙에서 요구하는 위치 외에, 하나의 ASCII 공백은 다음에서만 나타납니다.

  1. if, for, catch와 같은 예약어 뒤에 나오는 여는 괄호(() 앞
  2. elsecatch과 같은 예약어 앞에 나오는 닫는 중괄호(}) 앞
  3. 아래 두 예외를 제외한, 모든 여는 중괄호(}) 앞
    • @SomeAnnotation({a, b}) (공백이 사용되지 않습니다.)
    • String[][] x = {{"foo"}}; (아래 9번 항목에 의해 {{사이에 공백이 필요하지 않습니다.)
  4. 이항 또는 삼항 연산자 기호 앞, 뒤. 이는 "operator-like"기호들에도 적용됩니다.
    • 인접한 타입바운딩의 앰퍼샌드: <T extends Foo & Bar>
    • catch 블록에서 여러 예외를 핸들링 할 때 파이프:
      catch(FooException | BarException e)
    • 향상된 for("foreach")문의 콜론(:)
    • 람다 표현의 화살표: (String str) -> str.length()
      하지만 아래에서는 적용 될 수 없습니다.
    • Object::toString과 같은 메서드 참조의 콜론(::) 두개
    • object.toString()과 같은 점 구분 기호
  5. ,:;뒤나 캐스팅 할 때 닫는 괄호()) 뒤
  6. 주석을 시작하는 더블 슬래시(//)와 모든 컨텐츠 사이, 공백 여러개가 허용됩니다.
  7. 더블 슬래시와 주석 내용 사이. 공백 여러개가 허용됩니다.
  8. 선언 시 변수 타입과 이름 사이: List<String> list
  9. 배열 선언 시 중괄호 내부에서 선택적으로 허용
    • new int[] {5, 6}new int[] { 5, 6 } 둘 다 가능합니다.
  10. 타입 애너테이션과 대괄호[] 또는 ...

이 규칙은 줄의 시작이나 끝에서 추가적인 공백을 요구하거나 금지하는것은 아닙니다.; 내부 공간만을 다룹니다.

4.6.3 가로 정렬: 요구되지 않음

용어 참고: 가로 정렬은 특정 토큰이 이전 줄의 다른 토큰 바로 아래에 나타나도록 코드에 여러개의 공백을 추가하는 방법입니다.

이 방법은 허용됩니다. 하지만 Google 스타일에서 요구되는것은 아닙니다. 이미 사용된 위치에서 정렬을 유지할 필요가 없습니다.

다음은 정렬 없이, 정렬하여 사용하는 예시들 입니다.:

private int x; // 괜찮습니다.
private Color color; // 마찬가지로 괜찮습니다.

private int   x;      // 허용됩니다, 향후 편집합니다.
private Color color;  // 정렬하지 않은 패 둘 수 있습니다.

: 정렬은 가독성을 높일 수 있지만, 향후 유지보수에 문제를 일으킬 수 있습니다. 나중에 단 한 줄만 수정하는것을 고려해보십시오. 이 수정으로 괜찮은 포맷을 망칠 수 있으며, 허용됩니다. 더 자주 코더(아마도 당신)에게 근처 라인 공백을 맞추라는 메세지를 표시하며, 일련의 재구성을 불러 일으킬 수 있습니다. 그 한줄의 수정은 "폭발 반경"을 가집니다. 이는 최악의 무의미한 작업을 초래할 수 있고, 버전 기록 정보를 손상시키고, 검토자의 속도를 저하시키고 머지충돌을 발생 시킵니다.

4.7 그룹 괄호: 권장됨

선택적으로 괄호를 그룹화 하는것은 작성자와 검토자가 코드를 잘못 이해하거나 읽기 쉽게 만들 가능성이 없다고 동의하는 경우에만 생략됩니다. 모든 사람이 전체 자바 연산자 우선순위 테이블을 기억한다고 가정하는것은 비합리적입니다.

4.8 특정 구조

4.8.1 열거형 클래스

열거형 상수 뒤에 오는 각각의 쉼표 뒤에 줄 바꿈은 선택사항입니다. 추가적인 빈 줄(보통 한 줄)또한 허용됩니다. 아래는 한가지 예제입니다.:

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

메서드와 설명이 없는 열거형 클래스는 배열 초기화처럼 포맷될 수 있습니다. (배열 초기화를 나타내는 섹션 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 필요할 때 선언

지역변수는 포함 블록이나 block-like 구조의 시작 부분에서 습관적으로 선언되지 않습니다. 대신 지역변수는 범위를 최소화하기 위해 처음 사용되는 지점(합당한)에 선언합니다. 지역변수는 선언과 동시에 초기화되거나 선언 직후 바로 초기화됩니다.

4.8.3 배열

4.8.3.1 배열 초기화: "block-like" 가능

모든 배열 초기화는 선택적으로 "block-like 구조" 처럼 포매팅 될 수 있습니다. 예를 들어, 아래 모든 상황을 허용합니다.(완전한 목록은 아닙니다.)

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

4.8.3.2 C-스타일 배열선언 금지

대괄호는 자료형의 일부를 구성합니다. 변수를 구성하지 않습니다.: String args[]가 아니라, String[] args

4.8.4 스위치문

용어 참고: 스위치 블록의 중괄호 내부에는 하나 이상의 구문 그룹이 있습니다. 각 구문그룹은 하나 이상의 명령문(또는 마지막 명령문 그룹의 경우, 0개 이상의 명령문)을 포함하는 하나 이상의 스위치 라벨들(case FPP:default: 모두)로 구성됩니다.

4.8.4.1 들여쓰기

다른 블록들과 마찬가지로, 스위치 블록 내용은 +2로 들여쓰기 됩니다.

스위치 라벨 뒤에는, 줄 바꿈이 있고, 들여쓰기 레벨은 블록이 열린것 처럼 +2가 추가됩니다. 스위치문이 끝나면 블록이 닫힌것 처럼 이전 들여쓰기 레벨로 돌아갑니다.

4.8.4.2 Fall-through: 주석

스위치 블록 내부에서, 각 구문 그룹은 갑자기 종료되거나(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 라벨 존재

각 스위치문은 default 구문이 아무런 코드를 포함하지 않더라도, 포함합니다.

예외: 열거형에 대한 스위치문은 모든 명시적 케이스를 처리한 경우 default 구문 그룹을 생략할 수 있습니다. 이를 통해 IDE 나 기타 분석도구는 경고를 표시할 수 있습니다.

4.8.5 애너테이션

4.8.5.1 타입 애너테이션

타입 애너테이션은 자료형 바로 앞에 붙을 수 있습니다. Taget(ElementType.TYPE_USE)같은 메타-애너테이션이라면 타입 애너테이션입니다. 예시:

final @Nullable String name;

public @Nullable Person getPersonByName(String name);

4.8.5.2 클래스 애너테이션

클래스에 적용되는 애너테이션은 문서 블록 바로 뒤에 나타나며, 각각은 사용되는 위치에(한줄에 하나씩) 정렬됩니다. 이 줄바꿈은 줄바꿈을 구성하지 않으므로(줄 바꿈 섹션 4.5), 들여쓰기 레벨은 증가하지 않습니다. 예시:

@Deprecated
@CheckReturnValue
public final class Frozzler { ... }

4.8.5.3 메서드와 생성자 애너테이션

직전 섹션과 통일하게 적용됩니다. 예시:

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

예외: 단 하나의 매개변수가 없는 애너테이션은 시그니처의 첫번째 라인에 같이 표시될 수 있습니다. 예시:

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

4.8.5.4 필드 애너테이션

필드에 붙은 애너테이션 또한 문서 블록 뒤에 붙을 수 있습니다. 그러나 이 경우 여러 애너테이션(매개변수화 되었을 가능성이 있는)은 같은 라인에 정렬됩니다.; 예시:

@Partial @Mock DataLoader loader;

4.8.6 주석

이 섹션에서는 구현 주석을 다룹니다. Javadoc 은 섹션 7에서 별도로 다룹니다.

매 줄 바꿈은 임의의 공백 뒤에 구현 설명이 나타날 수 있습니다. 이러한 주석은 줄을 공백으로 만들지 않습니다.

4.8.6.1 블록 주석 스타일

블록 주석은 주변 코드와 동일한 레벨로 들여쓰기 됩니다. /* ... */스타일이나 // ...스타일이 될 수 있습니다. 여러줄 주석/* ... */의 경우 반드시 후속 줄이 *정렬된 것으로 시작돼야 합니다.

/*
 * 괜찮습니다.          // 괜찮습니다.           /* 이것도 
 *                   //                     * 괜찮습니다. */
 */

주석은 별표나 기타 다른 문자로 그려진 박스에 포함되지 않습니다.

: 여러 줄 주석을 작성 할 때 필요한 경우 코드 편집기가 필요한 경우(paragraph-style) 줄을 다시 정렬하도록 한다면 /* ... */스타일을 사용하세요. 대부분의 편집기는 // ...스타일 주석 블록에서 줄을 바꾸지 않습니다.

4.8.7 접근제한자

클래스나 멤버 접근제한자가 있다면, Java Language Specification 에 정의된 방식에 따라 작성됩니다.:

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

4.8.8 숫자 리터럴

long 형태의 정수 리터럴은 대문자 L 을 접미사로 붙입니다. 숫자 1과 구별하기 위함이므로 절대 소문자를 사용해서는 안됩니다. 예를 들어, 3000000000l 대신 3000000000L

5 이름짓기

5.1 모든 식별자에 대한 공통 규칙

식별자는 아래에 설명 할 몇몇 경우에 오직 ASCII 문자와 숫자, 밑줄만 사용합니다. 그래서 유효한 식별자 이름은 \w+ 정규식 규칙에 들어맞습니다.

Google 스타일에서 특수접두사나 접미사는 사용되지 않습니다. 예를 들어, 이러한 이름들은 Google 스타일이 아닙니다.: name_mName, s_name, kName.

5.2 식별자 유형에 따른 규칙

5.2.1 패키지명

패키지명은 영어 소문자와 숫자만(밑줄 금지)을 사용합니다. 일반적으로 연속적인 단어들도 한꺼번에 작성됩니다. 예를 들어, com.example.deepㄴpacecom.example.deep_space가 아닌, com.example.deepspace로 명명됩니다.

5.2.2 클래스명

클래스명은 UpperCamelCase 로 작성합니다.

일반적으로 클래스명은 명사 또는 명사구 입니다. 예를 들어, CharacterImmutableList. 인터페이스명 또한 명사나 명사구로 표현됩니다만(예를 들어, List), 때때로 형용사나 형용사구로 표현될 수 있습니다.(예를 들어, Readable)

어노테이션명에 대한 특별하거나 잘 정립된 규칙은 없습니다.

테스트 클래스명은 항상 Test로 끝나야 합니다. 예를 들어, HashIntegrationTest. 만약 단일 클래스를 포함한다면 해당 클래스의 이름에 Test가 추가됩니다. 예를 들어 HashImplTest.

5.2.3 메서드명

메서드명은 lowerCamelCase 로 작성합니다.

일반적으로 메서드명은 동사 또는 동사구 입니다. 예를 들어, sendMessagestop.

JUnit 테스트 메서드명에서 밑줄이 표시되어 이름의 논리적 구성요소를 구분 할 수 있고, 각 구성요소들은 lowerCamelCase로 작성합니다. 예를 들어 transferMoney_deductsFromSource. 단 테스트 메서드명을 위한 하나의 정확한 방법은 없습니다.

5.2.4 상수명

상수명은 UPPER_SNAKE_CASE로 작성합니다.: 하나의 및줄로 구분되는 대문자. 하지만 상수란 무엇일까요?

상수는 내용이 완전히 불변하고 메서드에서 부작용을 찾을 수 없는 static final 필드입니다. 아래 예시는 기본 및 문자열, 불변 값 클래스, null로 설정된 모든 것들 입니다. 객체의 상태가 변할 수 있는 경우 상수라 할 수 없습니다. 단순히 오브젝트의 변경을 막는 것으로는 충분하지 않습니다. 예시:

// 상수
static final int NUMBER = 5;
static final ImmutableList<String> NAMES = ImmutableList.of("Ed", "Ann");
static final Map<String, Integer> AGES = ImmutableMap.of("Ed", 35, "Ann", 32);
static final Joiner COMMA_JOINER = Joiner.on(','); // Joiner는 불변입니다.
static final SomeMutableType[] EMPTY_ARRAY = {};

// 상수가 아닌 것들
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 로 작성합니다.

일반적으로 이 이름들은 명사 또는 명사구 입니다. 예를 들어, computedValuesindex.

5.2.6 매개변수명

매개변수명은 lowerCamelCase 로 작성합니다.

public 메서드에서 한글자 매개변수는 금지되어야 합니다.

5.2.7 지역변수명

지역변수명은 lowerCamelCase 로 작성합니다.

final 이거나 불변일 때에도, 지역변수는 상수로 간주되지 않고, 상수 스타일을 지정하지 않아야 합니다.

5.2.8 타입변수명

각각의 타입변수명은 다음 두 가지 스타일 중 하나가 적용됩니다.:

  • 하나의 영문 대문자, 선택적으로 하나의 숫자가 따라올 수 있습니다. (ET, X, T2 처럼)
  • 클래스에 사용되는(클래스명, 섹션 5.2.2 참조) 형식명위세 영문 대문자 T가 붙을 수 있습니다. (예를 들어, RequestT, FooBarT)

5.3 카멜케이스: 정의됨

때때로 두글자 단어나 "IPv6", "IOS"같은 일반적이지 않은 형태의 구조일 때 영문을 카멜케이스로 변환하는 합리적인 방법은 여러가지가 있습니다. 예측 가능성을 높이기 위해, Google 스타일은 다음과 같은 (거의)결정적인 형태를 지정합니다.

산문체로 시작합니다.:

  1. 프레이즈를 일반 ASCII 로 바꾸고 어퍼스트로피를 제거해야합니다. 예를 들어:
    "Müller's algorithm"은 "Muellers algorithm"으로 바뀔 수 있습니다.
  2. 결과를 공백과 나머지 구두점(보통 하이픈)으로 구분되는 단어별로 나눕니다.
    • 권장: 일반적으로 사용되는 카멜케이스 형태의 단어라면 이를 구성 성분(예를 들어, "AdWords"는 "ad words"가 됩니다.)으로 나눕니다. "IOS"같은 단어는 실제로 카멜케이스가 아님을 알립니다.; 이는 모든 규칙을 따르지 않으므로, 권장사항이 적용되지 않습니다.
  3. 이제 전부(약어를 포함해) 소문자로 바꾸고, 각 단어의 첫 문자만 대문자로 바꿉니다.:
    • ... 각 단어를 UpperCamelCase 로 바꾸거나,
    • ... 각 단어를 lowerCamelCase 로 바꿉니다.
  4. 마지막으로, 모든 단어를 단일 식별자로 결합합니다.

원래 단어의 대소문자는 거의 완전히 무시됩니다. 예를 들어:

Prose formCorrectIncorrect
"XML HTTP request"XmlHttpRequestXMLHTTPRequest
"new customer ID"newCustomerIdnewCustomerID
"inner stopwatch"innerStopwatchinnerStopWatch
"supports IPv6 on iOS?"supportsIpv6OnIossupportsIPv6OnIOS
"YouTube importer"YouTubeImporter YoutubeImporter*
  • 허용되지만 권장하지 않습니다.

참고: 영어에서 일부 단어들은 하이픈으로 모호하게 연결됩니다.: 예를 들어 "nonempty"와 "non-empty"는 모두 옳기때문에, 일부 checkNonemptycheckNonEmpty와 같은 메서드명은 옳습니다.

6 프로그래밍 실습

6.1 @Override: 항상 하용

@Override 가 허용 될 때 마다 어노테이션으로 표기합니다. 이는 상위 클래스 메서드 재정의와 인터퍼이스 메서드 구현, 상위 인터페이스 메서드를 재 지정하는 것을 포함합니다.

예외: @Override는 부모 메서드가 @Deprecated인 경우생략 될 수 있습니다.

6.2 예외잡기: 무시하지 않음

아래 작성된 경우를 제외하고, 예외를 잡고 아무것도 하지 않는것은 매우 드뭅니다. (일반적인 응답은 로그를 기록하거나, "불가능"하다고 고려될 경우 AssertionError로 다시 던집니다.)

catch 블록에서 아무것도 하지 않는것이 정말로 적절 할 때, 정당화 되는 이유를 주석으로 설명해야 합니다.

try {
    int i = Integer.parseInt(response);
    return handleNumericResponse(i);
} catch (NumberFormatException ok) {
    // 숫자가 아닙니다.; 괜찮으니 그냥 진행합니다.
}
return handleTextResponse(response);

예외: 테스트에서, 잡힌 예외의 이름이 expected거나 expected로 시작할 경우 주석 없이 무시될 수 있습니다. 다음은 테스트가 예외를 던질것이라는것을 보장하는 매우 일반적인 관용구이므로 주석이 필요 없습니다.

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

6.3 정적 멤버: 클래스로 정규화

정적 클래스 멤버에 대한 참조가 반드시 정규화되어야 하는 경우, 해당 클래스명으로 정규화 해야 합니다.

Foo aFoo = ...;
Foo.aStaticMethod(); // 좋음
aFoo.aStaticMethod(); // 나쁨
somethingThatYieldsAFoo().aStaticMethod(); // 매우 나쁨

6.4 Finalizers: 사용되지 않음

Object.finalize를 재정의하는 것은 극히 드뭅니다.

: 하지마세요. 정말로 해야하는 경우, 이펙티브 자바의 항목 , "아이템 8. finalizer와 cleaner 사용을 피하라."를 매우 주의깊게 읽고 이해한 뒤, 하지마세요.

7 Javadoc

7.1 형식화

7.1.1 일반 형식

Javadoc 블록의 일반적인 구조는 다음 예시와 같습니다.:

/**
 * 여러줄의 Javadoc 텍스트가 여기 작성됩니다,
 * 일반적으로 래핑됩니다 ...
 */
public int method(String p1) { ... }

... 또는 아래 한 줄 예시와 같습니다.:

/** 특히 짧은 Javadoc 입니다. */

기본 형식은 언제든 허용됩니다. 한 줄 형식은 Javadoc 블록(주석과 마커를 포함하는) 전체가 한 줄이 될 수 있을 경우 대체될 수 있습니다. 이는 @return과 같은 블록 태그가 없는 경우에만 적용됨을 알립니다.

7.1.2 문단

하나의 빈 줄-즉 정렬된 선행 별표(*)만이 포함된 줄-은 문단 사이에 나타나고, 블록 태그 그룹이 있는 경우 앞에 나타납니다. 첫번째를 제외한 각 문단은 첫번째 단어 앞에 공백 없이 <p>를 가집니다.

7.1.3 블록 태그

사용되는 표준 "블록 태그"는 @param, @return, @throws, @deprecated로 표시되며, 빈 설명으로 표시되지 않습니다.

7.2 요약 부분

각 Javadoc 블록은 간략한 요약 부분으로 시작합니다. 이 부분은 굉장히 중요합니다.: 클래스와 메서드의 인덱스처럼 특정 컨텍스트에 나타나는 텍스트의 유일한 파트입니다.

이는 완전한 문장이 아닌, 명사구나 동사구 부분입니다. 이는 Save the record.같은 완전한 명령문을 형성하지도 않고, A {@code Foo} is a...This method returns... 로 시작하지 않습니다. 그러나, 대문자로 쓰여져 있고 마치 완전한 문장인 것 처럼 구두점이 찍혀 있습니다.

: 흔한 실수는 간단한 Javadoc 을 /** @return the customer ID */ 와 같은양식으로 작성하는것 입니다. 이는 틀렸고, 반드시 /** Return the customer ID. */로 바뀌어야합니다.

7.3 Javadoc 이 사용되는 곳

아래 몇가지 예외와 함께 Javadoc 은 최소한, 모든 public클래스와, public또는 protected 멤버에 나타납니다.

요구되지 않는 Javadoc, 섹션 7.3.4에 설명 된 것 처럼 추가적인 Javadoc 컨텐츠 또한 나타날 수 있습니다.

7.3.1 예외: 자명한 멤버

Javadoc 은 getFoo()같은 정말 설명할 만한것이 "foo 를 반환한다."는 것 외에 아무것도 없는 경우와 같이 "단순하고, 명백한" 멤버들에 대한 선택사항입니다.

7.3.2 예외: 재정의

Javadoc 은 super 타입 메서드를 재정의하는 메서드에 항상 존재하는것은 아닙니다.

7.3.4 필수가 아닌 Javadoc

다른 클래스와 멤버는 필요하거나 원하는 대로 Javadoc 을 가집니다.

구현 주석이 클래스나 멤버의 전체적인 목적이나 동작을 정의하는 데 사용될 때는 언제나, 해당 주석은 Javadoc 으로(/**대신) 작성됩니다.

필수가 아닌 Javadoc 은 물론 권장되지만, 섹션 7.2과, 7.1.1, 7.1.2, 7.1.3 을 엄격하게 준수해야 하는 것은 아닙니다.

profile
Hi. I'm Neo

0개의 댓글