카테고리 없음

Google Java Style Guide

freeParksey 2022. 10. 29. 18:13

우테코 프리코스를 진행하면서 기왕이면 스타일 방식까지 제대로 해보고 싶어서 정리한다.

 

다른 Style Guide

  • Git Commit Style Guide

 

1. 소개


Java Programming 언어로 작성된 소스 코드에 대한 Google 표준 코딩입니다.

 

들어가기 전

  • 앞으로 나오는 Class : 기본 class, Enum class, interface, @interface를 모두 포함한 용어이다.
  • 클래스의 Member : Nested class, field, method, 생성자를 표괄한 내용
  • comment : 주석

 

 

2. 소스파일의 기본


1. 파일이름 

해당 파일의 최상위 클래스의 이름.java 확장자로 구성된다.

2. 파일 인코딩 

UTF-8

3. 특수 문자

3-1. 공백문자 : ASCII horizontal space character (0x20) 가 유일한 공백 문자이다.

3-2. 특수 escaoe 문자:  이스케이프 문자(\b, \t, \n, \f, \r, \", \', \\) 문자는 8진수(\012)나 유니코드 이스케이프 문자 대신 사용

3-3. Non-ASCII 문자 :  유니코드 문자나 유니코드 이스케이프 문자를 사용

  • 단. 유니코드 이스케이프 보다 유니코드 문자가 사용되는 경우에도 설명 주석은 필요하다
  • 가독성을 헤칠 필요는 없다

 

3. 소스 파일 구조


구성 순서

  1. 라이센스 or 저작권 정보 ( 존재한다면)
  2. 패캐지 구문
  3. import 구문
  4. 하나의 최상위 클래스

 

3.1 라이센스 or 저작권 정보 ( 존재한다면)

라이센스나 저작권 정보가 파일에 속할 경우

 

3.2 패키지 구문

줄바꿈 없이 하나의 줄로 표현

 

3.3 import 구문

1. No Wild card(*) import : wild card(*)를 사용하지 않는다.

 

2. No line-wrapping : 줄을 바꾸지 않는다.

 

3. Ordering and spacing : static import와 non-static import 둘다 하나의 블럭안에 포함

두개가 동시에 있는 경우 개행으로 두 개를 분리, 그 이외에는 개행이 있으면 안된다.

 

4. No static import for classes : static import는 nested class에 대해 사용되지 않는다.

 

3.4 클래스 정의

1. 정확히 하나의 최상위 클래스를 선언해야 한다.

각 최상위 클래스는 자기 자신의 소스파일에 있어야 한다.

 

2. 본문 내용 순서

순서에 정답은 없다. 다만 각 클래스가 논리적인 순서를 가져야 하며 유지보수자(관리자)가 요청하면 설명 가능해야한다.

(단. 작성 순서대로 추가하면 안된다.)

 

3.  Overload: 절대 분리 X

여러 개의 생성자들 or 같은 이름의 함수들은 모두 하나로 나타내야 한다.

 

 

4. Formatting


4.1 중괄호 ( {} )

1. 선택적인 중괄호의 사용

if, else, for, do, while 과 같은 구문에서  내용이 없거나 한 줄만 있어도 중괄호가 사용되어야 한다.

 

2. Non-empty 스타일 블록 ; K & R 스타일

Non-empty 중괄호 스타일 : Kernighan과 Ritchie 스타일을 따른다.

  • 여는 중괄호 앞 = 줄 바꿈 X,   여는 중괄호 뒤 = 줄 바꿈
  • 닫는 중괄호 전 = 줄 바꿈
  • 뒤에 else와 같이 오는 경우 = 줄 바꿈 X
  • 단,  Enum의 경우 예외

예제)

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-2. Empty 블럭 : 간결하게 할 수 있다.

  • 열자마자 닫을 수 있다.
  • 단 멀티 블럭 구문이면 불가 ( Ex. if/else, try/catch/finally)

 

4-3. 블럭 들여쓰기 : 2 space

  • 새 블록이 생성될 때마다 2space
  • 코드와 주석 모드 적용
  • 각 구문 뒤에는 줄 바꿈이 온다.

 

4-4. 열 제한 : 100

100 문자의 열 제한이 존재한다. 기준은 유니코드 기준이며 full-width(한국어, 중국어, 일본어) 의 경우 규칙보다 일찍 줄 바꿈하는게 좋다.

 

예외

  • Javadoc의 긴 URL or 긴 JSNL 메서드
  • package or import 구문
  • 쉘에 복사 붙여넣기 되는 command line 주석 

 

4-5. 줄 바꿈 : 하나의 줄 -> 여러 줄

열 제한을 넘지 않게 하기 위해 줄 바꿈을 한다. 다만 열 제한이 아니여도 작성자의 재량에 따라 줄 바꿈 가능

줄 바꿈대신 메서드나 지역 변수를 사용하여 대신할 수 있다.

 

줄 바꿈 규칙

  1. Non-assignment연산자에서의 줄 바꿈 : 기호 이전에 줄 바꾼다
    • dot separator(.)
    • two colons (::)
    • An ampersand in a type bound ( <>)
    • catch 블럭 : catch(Exception)
  2. assignment(대입) 연산자에서 줄이 끊어지면 일반적으로는 기호 뒤에 오지만 어느 쪽이든 허용
  3. 메서드나 생성자 뒤에 오는 여는 괄호가 있을때,  콤마 앞에 오는 토큰은 연결되어 있어야 한다.
  4. 람다식의 인접한 화살표에서는 안바뀌지면 한줄이면 변경 가능

2,3,4 예제.

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

Predicate<String> predicate = str ->
    longExpressionInvolving(str);
String someThing = new StringBuffer()
          .append("hello")
          .append("world");

String someThing = "hello"
                 + "world";

 

1. 줄 바꿈 들여쓰기 : 4 space

 

 

4-6 공백

1. 수직 공백 : 하나의 줄을 공백으로 두어 분리

  • 연속적인 멤버나 클래스의 초기화

수직 공백은 구독성을 향상시킬 수 있는 곳 어디에서나 사용 가능, 여러 개의 연속된 공백은 가능하지만 권장되지 않는다.

 

2. 수평 공백 

  1. 예약어 분리 : if, for, catch  같은 예약어 후 여는 괄호에서 사용
    • if (), for (), catch ()
  2. 예약어 분리 : else, catch 같은 예약어 후 닫는 괄호에서 사용
    • } else {, } catch [
  3. 배열 선언문에서는 공백 상관 없음
    1. new int[] {5, 6} or new int[] { 5, 6 }

 

3. 수평 정렬 : 권장되지 않음

가독성을 높여주지만. 추후의 유지보수에 문제를 일으킨다.

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

 

4-7 소괄호 그룹 : 사용하는 것을 추천

우선순위 연산자가 명확하더라도 소괄호로 감싸는 것을 추천

 

4-8 특별한 구조

1. Enum : 상수에 따라오는 콤마 뒤의 줄바꿈은 선택 사항, 또한 Class 이므로 클래스 포맷팅 형식 적용

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

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

 

2. 변수 선언 : 

한번에 하나만 : 변수 초기화는 한번에 하나만, int a, b; 이렇게 사용 안함

필요할 때 선언 : 지역변수는 블럭이 시작할 때 사용할 필요가 없다.  단 처음 사용할 때 가까운 위치에 선언

 

3. 배열:

배열 초기화:

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

 

배열 타입 선언: String[] args가 맞으며, String args[]는 틀리다.

 

4. Switch문

 

1.들여쓰기: Switch  블럭의 들여쓰기는 +2, 라벨 뒤에는 개행

2 실패 주석 : 각 구문들의 break, continue, return이나 다음 구문으로 실행이 넘어 갈때 주석을 할 수 있다.

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

 

3. default case : 해당 그룹이 필요하지 않더라도 포함한다. 단 enum타입의 switch는 default 생략 가능

 

5. Annotations : 클래스나 함수, 생성자에 적용된다. 들여쓰기 레벨이 증가되지 않는다.

  • 단 파라미터가 없는 단일 Annotation은 한줄에 쓸 수 있다.
  • field에 적용되는 Annotation은 파라미터가 있어도 한줄에 가능
@Deprecated
@Override
public String getNameIfPresent() { ... }
@Override public int hashCode() { ... }
@Partial @Mock DataLoader loader;

6. 주석 :

블럭 주석 스타일 : 

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

주석 내부에 주석을 사용하고 싶다면 /* */ 를 사용해야 한다.

 

7. 접근 제한자 순서

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

 

8. 숫자 리터럴 : Long 의 경우 l 대신 L을 사용하는데, 이는 숫자 1과 혼동이 있을 수 있기 때문이다.

 

5 네이밍


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

식별자 :  ASCII와 숫자, 일부는 _ 로 표현, 구글 스타일에는 특별한 접미사나 접두사를 사용 안함

 

2. 식별자 타입에 대한 규칙

  • 패캐지명 : 모두 소문자
  • 클래스 이름 : UpperCamelCase
    • 명사나 명사구
    • Test 클래스이면 마지막에 Test를 붙인다.
  • 함수 이름 : lowerCamelCase
    • 동사나 동사구
    • 테스트 메서드 이름엔 정답이 없습니다.
  • 상수 이름: CONSTANT_CASE
    • 모두 대문자, 각 단어는 하나의 언터스코어로 구분
    • static final
  • 상수를 제외한 필드 이름 : lowerCamelCase
    • Ex. 파라미터, 지역 변수, 함수 이름
  • 타입 변수 이름 : 클래스를 위해서 사용 되는 이름 형식에 T가 따라온다. (Ex. RequestT, FooBarT)

[CamelCase]

Prose form Correct Incorrect
"XML HTTP request" XmlHttpRequest XMLHTTPRequest
"new customer ID" newCustomerId newCustomerID
"inner stopwatch" innerStopwatch innerStopWatch
"supports IPv6 on iOS?" supportsIpv6OnIos supportsIPv6OnIOS
"YouTube importer" YouTubeImporter
YoutubeImporter*
 

 

6. 프로그래밍 학습


1. @Override : always used

메서드가 Override가 되면 항상 Anootation을 붙여준다. 모든 상황에서 모두 포함

(단 @Deprecated된 경우 @Override 생략 가능)

 

2. Caught exceptions: not ignored

예외를 잡고 아무것도 안하면 안된다. 아무것도 안 할려면 주석을 남겨야 한다.

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로 예외를 넘어갈 수 있다.

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

 

3.  정적 멤버 : 클래스 사용

static 클래스 멤버 참조는 그에 대한 자격이 있어야 한다.

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

 

4. Finalizers : 사용되지 않는다.

Object.finalize : 사용하지 마라, Effective Java Item 8을 참고

 

 

7. Javadoc


1. Formatting

General form

/**
 * Multiple lines of Javadoc text are written here,
 * wrapped normally...
 */
public int method(String p1) { ... }

or (단 @return과 같은 블록 태그가 없는 경우에만 해당)

/** An especially short bit of Javadoc. */

 

Block Tags

block tag는 4가지 type이 있는데 @param, @return, @throws, @deprecated가 있다. 또한 이 4개는 설명이 무조건 있어야 한다. 한줄에 쓸 수 없다면 다음 줄은 @ 위치에서 들여쓰기 4번 한다.

 

2. The summary fragment

각 javadoc 블록은 간단한 요약 부분으로 시작된다. 

A {@code Foo} is a This method returns 같이 시작하지 않는다.

/** @return the customer ID */. 나  /** Returns the customer ID. */.처럼  변경해야 한다.

 

3. Javadoc이 사용되는 위치

모든 public 클래스나 public, protected 멤버에 사용된다.

 

 

참고 문헌


Google Java Style Guide

 

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