본문 바로가기
General

[Google Java Convention] 구글의 자바 컨벤션 정리

by whatamigonnabe 2023. 1. 26.

본 글은 아래 구글의 문서를 정리한 것입니다.

 

Google Java Style Guide

1 Introduction This document serves as the complete definition of Google's coding standards for source code in the Java™ Programming Language. A Java source file is described as being in Google Style if and only if it adheres to the rules herein. Like ot

google.github.io

Java Convention

Source file

  • 파일 명
    • 대소문자를 구별하는 최상위 클래스 이름 뒤에 .java를 붙인다.
  • 특수 문자
    • 공백 문자
      • 줄 끝내기 문자를 제외하고, ASCII의 0x20( = 일반적인 스페이스)만이 유일한 공백문자이다.
      • 이 이외의 공백문자들은 escaped된다.
      • Tab은 들여쓰기에 사용하지 않는다.
    • 특수 이스케이프 문자들
      • 아래 특수 이스케이프 문자열은 같은 의미의 옥텟이나 유니코드 대신에 아래의 문자열을 사용한다.
    • ASCII가 아닌 문자들의 표현
      • 실제 문자(∞)를 쓰는 것이 유니코드(\u221e)보다 더 읽기 쉽기 때문에 권장된다!
  • 소스 파일 구조
    • 아래의 구성요소들이 각 한 줄씩 띄어서 작성한다.
      • License or copyright (존재한다면)
      • Package 문장 (줄 바꿔 쓰지 않는다)(열 제한(column limit)가 적용되지 않는다.)
      • Import 문장
      • 단 하나의 최상위 클래스
    • Import 문장
      • wildchard import는 사용하지 않는다.
      • 줄 바꿔 쓰지 않는다. 열 제한이 적용되지 않는다.
      • static import를 모아서 한 블럭, non-static import를 모아서 한 블럭 작성한다.
      • static import 블러과 non-static import 블럭 사이에 한 줄을 띈다.
      • ASCII 순으로 정렬한다.
      • static import는 static nested clasess를 위해 사용되지 않는다. 일반적인 import로 import한다.
  • Class 선언
    • 하나의 파일에 최상위 클래스는 하나
    • 클래스의 멤버들의 순서
      • 정해진 건 없지만, 논리적으로 설명할 수 있어야한다.
      • overload한 생성자 혹은 메서드들은 하나로 뭉쳐서 작성한다.

Formatting

  • 괄호
    • 선택적 괄호의 사용
      • if, else, for , do, while 의 괄호안의 본문이 비어있거나 한 줄만 있는 경우에도 괄호를 사용한다.
      • 다른 괄호( lambda 표현)는 선택적으로 사용한다.
    • K & R style (비어있지 않는 블럭)
      • 괄호는 Kernighan and Ritchie style을 따른다.
        • 여는 괄호 전에 줄 바꿈 사용하지 않는다.
        • 여는 괄호 뒤에서 줄 바꾼다.
        • 닫는 괄호 앞에서 줄 바꾼다.
        • 닫는 괄호 뒤에서 줄 바꾼다. 다만 구문이 끝나거나 메소드, 생성자, 클래스가 끝났을 때만 적용됨. else나 콤마가 뛰따라지는 괄호 다음에는 줄 바꿈 하지 않는다.
    • 빈 블럭
      • 빈 블럭은 괄호가 줄바꿈 없이 바로 닫힐 수 있다.({}) 다만, 다중 블럭 구문(if/else or try/catch/finally에서는 바로 닫으면 안된다.
      • try { doSomething(); } catch (Exception e) {} // 안됨
  • Block indentation: +2 spaces
    • 새로운 블락이나 블락같은 구조가 열리면 두 칸을 들여쓴다.
    • 이것은 코드나 주석에도 똑같이 영향을 준다.
  • 한 줄에 한 문장을 작성한다.
  • 열 제한 : 100
    • 100 문자(여기서 문자는 유니코드의 문자)의 제한이 있다.
    • 이 제한을 넘기면 Line-wrapping(줄바꿈)을 해야한다.
    • 예외들
      • 긴 URL이나 긴 JSNI는 애초에 지킬 수가 없음
      • package나 import 문장들
      • shell에 복사 붙여넣기 된 주석 속의 명령문
      • 매우 긴 식별자
  • Line-Wrapping (긴 한 줄이 몇 줄로 나뉘는 것)
    • 정해진 방법은 없다. 같은 한 줄이라도 여러 다른 방법으로 될 수 있다.
    • 메서드나 직역 변수를 추출하는 것은 Line-Wrapping을 피하는 방법이 될 수 있다.
    • where to break
      • 높은 문법 수준에서 줄바꿈해라
        • non-assignment 연산자에서 줄 바꿈이 일어날 경우 기호 이전에서 바꾼다. 이것은 연산자와 유사한 기호들에 적용된다.
          • .
          • ::
          • 엠퍼샌드 <T extends Foo & Bar>
          • catch 블락 속의 a pipe (catch (FooException | BarException e))
        • assignment 연산자 다음에 줄바꿈 하지만, 전에 해도 괜찮다. 향상된 for문에 안의 assignment와 유사한 콜론(:)에도 적용된다.
        • 메서드 또는 생성자의 이름은 여는 소괄호(()에 붙는다.
        • 컴마(,)는 앞선 토큰(문자)에 붙는다.
        • 람다 표현식의 화살표 근처에서는 줄바꿈 하지 않는다. 다만, 람다의 본문이 한 줄인 경우네는 화살표 뒤에서 바로 들여쓸 수 있다.
        • MyLambda<String, Long, Object> lambda = (String label, Long value, Object obj) -> { ... }; Predicate<String> predicate = str -> longExpressionInvolving(str);
        • line wrapping의 목적은 가독성을 높이는 것이지, 라인 수를 줄이는 것이 아니다.
      • 이어지는 라인의 들여쓰기는 최소 +4 스페이스
        • line-wrapping에서 줄 바꿈 할 때 최소 4개의 스페이스는 들여쓴다.
        • 여러 이어지는 줄이 생길 경우 들여쓰기는 4 스페이스를 넘을 수 있다.
        • 문법적으로 평행한 요소들로 linewrapping할 때만 같은 수순의 들여쓰기를 한다.
    • 공백 문자
      • 수직 공백
        • 아래의 경우 하나의 공백 줄은 항상 나타난다.
          • 연이은 필드, 생성자, 메소드, 이너 클래스, 정적 초기화, 인스턴스 초기화 사이에서
            • 예외: 두 개의 이어지는 필드 사이의 공백은 선택이다. 논리적인 그루핑할 때 띄어쓰는 게 좋다.
            • 예외 : enum 상수들 사이의 공백도 선택적
        • 이외에도 한줄의 공백줄은 어디서든 가독성을 높이기위해 사용될 수 있다.
        • 연속된는 공백 줄은 권장되지 않는다.
      • 수평 공백
        • 다음의 예약어(if, for, each)와 여는 소활호(()사이에서는 띄어쓴다.
        • 다음의 예약어(else, catch)와 닫는 중괄호 (}) 사이에서 띄어쓴다.
        • 모든 여는 중괄호({) 앞에서 띄어쓴다.
          • 예외: @SomeAnnotation({a, b})
          • 예외: String[][] x = {{"foo"}};
        • 모든 이항 또는 삼항 연산자의 양쪽에서 띄어쓴따.
          • 연산자와 유사한 아래의 symbol에서도 양쪽을 띄어쓴다.
            • <T extends Foo & Bar>
            • catch (FooException | BarException e)
            • 향상된 for 문의 콜론 (:)
            • 람다의 화살표
          • 아래의 경우는 띄어쓰지 않는다.
            • Object::toString
            • object.toString()
            • , : ; ) 뒤에서 띄어쓴다.
            • 주석을 시작하는 //과 문장 사이에서 띄어쓴다. 여러 번 가능.
            • List<String> ``list
            • 배열 초기화의 괄호 양쪽에 띄어도 안띄어도 된다.
              • new int[] {5, 6} and new int[] { 5, 6 } are both valid
            • type annotation 과 [] or ... 사이에서 띄어쓴다.
      • 수평 맞춤 : 절대 권장되지 않음
      • private int x; // permitted, but future edits private Color color; // may leave it unaligned
      • 그루핑을 위한 괄호는 권장됨
      • 특별한 구조들
        • Enum 클래스
          • Enum상수 다음의 콤마 뒤에 한 줄 또는 두 줄 띄는 것 가능
          • 메서드와 doc이 없는 enum클래스도 선택적으로 가능
            • private enum Suit { CLUBS, HEARTS, SPADES, DIAMONDS }
        • 변수 선언
          • 한 줄에 하나의 변수만 선언한다. int a, b; : 안됨
            • 예외: for 문
          • 지역 변수를 습관적으로 한 블락이 시작될 때 선언하지 않는다. 대신, 이 변수가 사용되는 곳과 가까운 곳에서 선언한다. 선언과 동시에 초기화하거나 직후에 초기화하는 것이 권장된다.
        • 배열
          • 배열 초기화 : 블락처럼
          • new int[] { new int[] { 0, 1, 2, 3 0, } 1, 2, new int[] { 3, 0, 1, } 2, 3 } new int[] {0, 1, 2, 3}
          • C-style(ex. String args[])로 선언하지 않는다.
        • Switch 문
          • 다른 블락처럼 2칸 들여쓴다.
          • Fall-through는 주석을 단다.
          • switch (input) { case 1: case 2: prepareOneOrTwo(); // fall through case 3: handleOneTwoOrThree(); break; default: handleLargeNumber(input); }
          • 코드가 없더라도 default label을 작성한다.
            • 예외 : 모든 경우를 작성한 enum에 대한 switch에서는 작성하지 않아도 됨.
        • Annotation
          • Type-use annotation
            • @Target(ElementType.TYPE_USE)으로 meta-annotated된 어노테이션들은 annotated된 타입 바로 전에 붙는다.
              • final @Nullable String name;
          • 클래스 / 메서드 / 생성자 어노테이션
            • document block 바로 뒤에 붙고, 한 줄에 하나의 어노테이션을 적는다.
            • @Deprecated @CheckReturnValue public final class Frozzler { ... }
            • 예외 : 한 줄인 메서드나 생성자는 어노테이션도 한 줄에 적을 수 있다.
            • @Override public int hashCode() { ... }
          • 필드 어노테이션
            • documentation block 바로 뒤에 붙는다. 여러 개의 어노테이션이 한줄에 붙을 수도 있다.
            • @Partial @Mock DataLoader loader;
          • 파라미터나 지역변수 어노테이션
            • 특별한 규칙은 없다.
        • 주석
          /*
           * This is          // And so           /* Or you can
           * okay.            // is this.          * even do this. */
           */
          
        • 여러 줄을 쓴다면 /* … */를 사용한다.

Naming

  • 식별자는 ASCII 문자로 작성하여 정규식의 \\w+가 매칭되도록 한다.
  • 구글 스타일에서는 특별한 prefix나 suffix를 사용하지 않는다.
    • name_, mName, s_name and kName
  • Package 명
    • 오직 소문자와 숫자만 사용한다(_ 사용하지 않는다.)
    • com.example.deepspace, not com.example.deepSpace or com.example.deep_space
  • Class 명
    • UpperCamelCase를 사용한다.
    • 명사나 명사구를 사용한다.
    • 테스트 클래스는 끝에 Test를 붙인다.
    • 테스트 클래스가 하나의 클래스만 커버한다면, 그 클래스명 뒤에 Test를 붙인다.
  • Method명
    • LowerCamelCase를 사용한다.
    • 동사나 동사구를 사용한다.
  • 상수 명
    • UPPER_SNAKE_CASE를 사용한다.
  • 상수가 아닌 필드 명, 매개변수명, 지역변수명
    • LowerCamelCase
    • 명사나 명사구
    • 지역변수는 final이나 immutable이더라도 상수로 취급하지 않는다.
  • 타입 변수 명
    • 하나의 대문자로 표현

Programming Practices

  • @Override는 항상 사용한다.
  • Caught exception은 비우지 말고, 꼭 작성한다.
    • 테스트에서 기대된 예외에서는 작성하지 않아도 된다.
  • Static members는 항상 클래스를 명시해서 사용한다.

Javadoc

  • 일반적인 포맷
    /** An especially short bit of Javadoc. */
    
    한 줄에 담을 수 있으면, 한 줄도 가능. 하지만 @return과 같은 블럭 태그가 없을 때만 가능.
  • /** * Multiple lines of Javadoc text are written here, * wrapped normally... */ public int method(String p1) { ... }
  • 문단
    • 맨 앞에 <p>를 적고 , 빈칸을 두지 않고 내용을 작성한다.
    • 문단과 문단사이에는 한줄을 띈다. 즉, * 하나만 있다.
  • Block Tags
    • **@param, @return, @throws, @deprecated 가 순서대로 쓰인다. 이걸 쓸려면 꼭 설명을 붙여야한다.**
    • 설명이 길어지면 줄바꿈 후 네 칸을 들여쓰고 이어 작성한다.
  • The summary fragment
    • Javadoc은 짧은 summary fragment로 시작한다.
    • 이것은 짧게 이 기능을 설명한다.
    • 완성된 문장이 아닌 명사구나 동사구로 작성한다.
  • Javadoc을 작성해야하는 곳
    • 최소한, 모든 public class와 이것의 public 또는 protected 멤버에 작성되어야하고, 몇 예외를 밑에 달아야한다.
    • 예외: 너무 당연한 것에는 사용하지 않다.
    • 예외: overrides
    • 주석을 설명이 필요하다면, Javadoc으로 작성한다.