공부/JAVA

더 나은 개발 문화를 위해 #1 코딩 스타일 가이드(Google Java Style Guide 번역)

JangGiraffe 2023. 10. 3. 18:26

더 나은 개발 문화를 위해 #1 코딩 스타일 가이드(Google Java Style Guide 번역)


 

AI로 생성한  Google Java Style Guide 이미지. 나중에 포스팅하겠다!

 

추석을 맞아 여유가 생겼다.

지금껏의 회사생활을 돌아보면 일하면서 여러 사람들과 같은 서비스를 유지보수할 때, 특별한 규칙 없이 각자 유지보수 해왔던 것 같다.
그래서 팀원들과의 유대감이나 서비스에 대한 애정이 좀 덜 했던 것 같음. 이 상황에서 소위 말하는 네카라쿠배의 좋은 개발문화들은 너무나도 부러웠다.
좋은 개발문화를 정착시키고 싶다는 생각이 있었는데, 이젠 이 회사에서 짬도 찼고 부사수도 둘이나 있고 해서 이분들과 함께 한번 해보려구 함.(아직 부사수들의 생각은 안물어봐서 조금 걱정되긴 하다.😢)

내가 생가하는 우리 회사에 필요한 부분은 크게 3가지 + 숙제..

  1. 코드 스타일 가이드 : 아직 시작 안함
  2. 코드리뷰 : 시작한지 얼마 안됨. 스타일가이드를 적절히 녹이면 될 듯 한데, 나의 코딩 실력이 그리 좋은 편은 아니어서 나도 좀 공부가 되는것 같음. 시간 갈아넣어야함
  3. 내부 스터디(세미나 등) : 시작한 지 두달정도 됐는데, 매 주 적절한 주체가 나오는 보장이 없어서 유지하는게 쉽지 않을듯하지만 잘 하구 있다.
  • 이거를 업무를 하며 자연스럽게 녹여야 하기 때문에 시행착오가 좀 있을듯 한데 중요한거는 이것 때문에 업무 퍼포먼스는 절때 떨어지면 안된다는거.. 괜히 눈총받을 수 있을듯 하니 조심하자.

회사에서 따로 쓰는 코딩 규칙이 없어 유지보수 효율이 좀 떨어지는 것 같아 찾아보다 구글 자바 스타일 가이드를 발견했다.
같이 일하는 분들과 다음 가이드에 맞춰보려고 한다. (번역은 챗GPT,파파고등을 활용함)

기대효과를 생각해보면 다음과 같으려나

  • 코드를 짜는것 보다 읽는데 쓰는 시간이 많은 데, 스타일을 적용할 경우 가독성이 좋아진다.
  • 코딩 스타일이 맞춰 져 코드리뷰에 도움이 됨

아래 문서 : https://google.github.io/styleguide/javaguide.html


👍 포스팅 진짜 시작 !

  • 개인 의견은 ✏️개인의견 로 표기 했습니다.

1. 코딩 스타일 가이드( with Google Java Style Guide)

목차

  • 1. 소개
    • 1.1 용어설명
    • 1.2 가이드노트
  • 2.소스파일기본사항
    • 2.1파일이름
    • 2.2파일인코딩:UTF-8
      • 2.3 특수 문자
  • 3.소스파일구조
      - 3.1 라이선스 또는 저작권 정보 (있는 경우)
      - 3.2 패키지 선언
      - 3.3 임포트 문
      - 3.4 클래스 선언
  • 4.포멧팅(서식)
      - 4.1 중괄호
      - 4.2 블록 들여쓰기
      - 4.3 한줄에 하나의 문장
      - 4.4 열제한 : 100
      - 4.5 줄바꿈
      - 4.6 공백
      - 4.7 그룹화 괄호: 권장됨
      - 4.8 특정한 구조체
  • 5.명명(네이밍)
      - 5.1 모든 식별자에 대한 공통 규칙
      - 5.2 식별자 유형별 규칙
  • 6. 프로그래밍 관행
      - 6.1 @Override: 항상 사용
      - 6.2 처리된 예외: 무시하지 않음
      - 6.3 Static 멤버 : 클래스를 사용
      - 6.4 파이널라이저: 사용하지 않음
  • 7. JavaDoc

1. 소개

이 문서는 Java™ 프로그래밍 언어의 소스 코드에 대한 Google 코딩 표준의 완전한 정의로 제공됩니다. Java 소스 파일은 여기에 규정된 규칙을 준수하는 경우에만 Google 스타일로 설명됩니다.

기타 프로그래밍 스타일 가이드와 마찬가지로 다루는 주제는 서식의 미학적 문제뿐만 아니라 다른 유형의 규칙 또는 코딩 표준도 포함됩니다. 그러나 이 문서는 주로 우리가 보편적으로 따르는 엄격한 규칙에 중점을 두며, 인간 또는 도구에 의해 명확하게 시행 가능하지 않은 조언을 제공하는 것을 피하고 있습니다.

1.1 용어 설명

본 문서에서 별도로 명시하지 않는 한 다음을 따릅니다.:

  1. 클래스라는 용어는 "보통" 클래스, 열거형 클래스, 인터페이스 또는 어노테이션 유형(@interface)을 포함하는 의미로 사용됩니다.
  2. 멤버(클래스의)라는 용어는 중첩 클래스, 필드, 메서드 또는 생성자를 의미하는 포괄적으로 사용되며,
    즉, 초기화자와 주석을 제외한 클래스의 모든 최상위 내용을 포함합니다. (😢that is, all top-level contents of a class except initializers and comments.)
  3. 주석이라는 용어는 항상 구현 주석을 가리킵니다. "문서 주석"이라는 구문은 사용하지 않으며 대신 일반적인 용어 "Javadoc"을 사용합니다.

1.2 가이드 노트

본 문서의 예제 코드는 비규범적입니다(일반적이지 않다?). 즉, 예제는 Google 스타일로 작성되었지만 코드를 나타내는 유일한 세련된 방식이 아닐 수 있습니다. 예제에서 선택적으로 사용된 서식 선택 사항은 규칙으로 강제되지 않아야 합니다.

2 소스 파일 기본사항

2.1 파일 이름

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

2.2 파일 인코딩: UTF-8

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

2.3 특수 문자

2.3.1 공백 문자

개행 시퀀스를 제외한 ASCII 수평 공백 문자(0x20)만 소스 파일 어디에서나 나타납니다. 이는 다음을 의미합니다:

  1. 문자 및 문자 리터럴에서 나머지 모든 공백 문자는 이스케이프 처리됩니다.
  2. 탭 문자는 들여쓰기에 사용되지 않습니다.

2.3.2 특수 이스케이프 시퀀스

특별한 이스케이프 시퀀스(\b, \t, \n, \f, \r, \", \'\\)가 있는 문자에 대해서는 해당 시퀀스가 대응하는 팔진수(예: \012) 또는 유니코드(예: \u000a) 이스케이프 대신 사용됩니다.

2.3.3 비 ASCII 문자

나머지 비 ASCII 문자에 대해서는 실제 유니코드 문자 (예: ) 또는 해당 유니코드 이스케이프 (예: \u221e) 중 어느 것을 사용할지는 코드를 더 읽고 이해하기 쉽게 만드는 것에만 의존합니다. 그러나 문자열 리터럴 및 주석 외부에서 유니코드 이스케이프를 사용하는 것은 강력히 권장하지 않습니다.

- Best: 코멘트가 없어도 완벽하게 명료합니다.
String unitAbbrev = "μs";
- 허용 : 굳이?
String unitAbbrev = "\u03bcs"; // "μs"
- 허용 : 실수할 가능성이 있음.
String unitAbbrev = "\u03bcs"; // Greek letter mu, "s"
- 안됨 : 읽는이는 이게 뭔지 모름
String unitAbbrev = "\u03bcs";
-좋은 방법: 출력할 수 없는 문자에 대해 이스케이프를 사용하고 필요한 경우 주석을 추가하세요.
return '\ufeff' + content; // byte order mark

3 소스 파일 구조

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

  1. 라이선스 또는 저작권 정보 (있는 경우)
  2. 패키지 선언
  3. 임포트 문
  4. 정확히 하나의 최상위 클래스

있는 섹션 간에는 정확히 한 줄의 빈 줄로 구분됩니다.

/*  //1. 라이선스 또는 저작권 정보 (있는 경우)
Copyright 2023-10-03 janggiraffe
...
*/

//2. 패키지 선언
package com.janggiraffe

//3. 임포트문
import java.util.Arrays;

import static java.math.BigInteger; // 정적(static)클래스 import 는 비스태틱 클래스 임포트와 한줄 띔

// 4. 정확히 하나의 최상위 클래스
public Class Giraffe {
  ...
}

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

라이선스 또는 저작권 정보가 파일에 속한다면, 이곳에 속합니다.

3.2 패키지 선언

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

3.3 임포트 문

3.3.1 와일드카드(*) 임포트 금지

와일드카드 임포트, 정적 또는 그 외의 형태로 사용되지 않습니다.

// 좋은 예: 특정 클래스만 가져옵니다.
import java.util.ArrayList;
import java.util.HashMap;

// 나쁜 예: 와일드카드 임포트를 사용하지 않습니다.
import java.util.*; // 이런 형태의 임포트는 피하세요.

3.3.2 줄 바꿈 금지

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

3.3.3 정렬 및 간격

임포트는 다음과 같은 순서로 정렬됩니다:

  1. 모든 정적 임포트는 하나의 블록에 포함됩니다.
  2. 모든 정적이 아닌 임포트는 하나의 블록에 포함됩니다.

정적 및 정적이 아닌 임포트가 모두 있는 경우, 두 블록 사이에 단일한 빈 줄이 있습니다. 다른 임포트 문 사이에는 다른 빈 줄이 없습니다.

각 블록 내에서 가져온 이름은 ASCII 정렬 순서로 나타납니다. (참고: 이것은 임포트 문이 ASCII 정렬 순서에 있는 것과는 다릅니다. '.'는 ';' 앞에 정렬됩니다.)

3.3.4 클래스에 대한 정적 임포트 금지

정적 중첩 클래스에 대한 정적 임포트는 사용되지 않습니다. 이러한 클래스는 일반적인 임포트로 가져옵니다.

3.4 클래스 선언

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

각 최상위 클래스는 별도의 소스 파일에 위치합니다.

3.4.2 클래스 내용의 순서

클래스의 멤버 및 초기화자의 순서를 선택하는 것은 학습 가능성에 큰 영향을 미칠 수 있습니다. 그러나 어떻게 해야 하는지에 대한 단일 올바른 정답은 없습니다.
서로 다른 클래스는 내용을 서로 다른 방식으로 정렬할 수 있습니다.

중요한 것은 각 클래스가 유지 관리자가 요청 시 설명할 수 있는 논리적인 순서를 사용하는 것입니다.
예를 들어, 새로운 메서드는 클래스의 끝에만 추가되지 않습니다. 왜냐하면 그렇게 하면 "추가된 날짜별" 순서가 나타나며 이것은 논리적인 순서가 아닙니다.

3.4.2.1 오버로드: 절대 분리하지 않습니다

동일한 이름을 가진 클래스의 메서드는 다른 멤버가 없는 연속된 그룹에서 나타납니다. 동일한 이름을 가진 여러 생성자에도 동일한 규칙이 적용됩니다(이 생성자는 항상 동일한 이름을 가집니다). 이 규칙은 메서드 간에 static 또는 private와 같은 접근제어자가 다를 때도 적용됩니다.

4. 포멧팅(서식)

4.1 중괄호

4.1.1 선택적 중괄호 사용

중괄호는 if, else, for, dowhile 문과 함께 사용되며 본문이 비어 있거나 하나의 문장만 포함되어 있더라도 사용됩니다.
람다 표현식과 같은 다른 선택적 중괄호는 선택 사항으로 유지됩니다.

if (condition) {
    // 본문이 비어 있지 않은 경우
    ...
}

if (condition)
    doSomething(); // 본문이 하나의 문장만 포함되어 있는 경우

someList.forEach(item -> doSomething(item)); // 선택적 중괄호는 여전히 선택사항입니다.

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

중괄호는 비어 있지 않은 블록 및 블록과 유사한 구조에 대해 Kernighan and Ritchie 스타일("이집트 중괄호")을 따릅니다:

  1. 여는 중괄호 앞에 줄 바꿈이 없습니다. (아래에서 자세히 설명한 경우 제외)
  2. 여는 중괄호 다음에 줄 바꿈이 있습니다.
  3. 닫는 중괄호 앞에 줄 바꿈이 있습니다.
  4. 닫는 중괄호 다음에 줄 바꿈이 있습니다. 이 줄 바꿈은 해당 중괄호가 문을 종료하거나 메서드, 생성자 또는 명명된 클래스의 본문을 종료하는 경우에만 있습니다. 예를 들어, else 또는 쉼표가 뒤 따르는 경우 중괄호 뒤에 줄 바꿈이 없습니다.
  5. 예외: 이러한 규칙이 세미콜론으로 끝나는 단일 문을 허용하는 경우, 문 블록이 나타날 수 있으며, 이 블록의 여는 중괄호 앞에 줄 바꿈이 있습니다. 이러한 블록은 일반적으로 지역 변수의 범위를 제한하기 위해 도입되며, 예를 들어 switch 문 내에서 사용됩니다.
  • 예제 :
return () -> {  // 1.여는 중괄호 앞에 줄 바꿈이 없습니다.
  while (condition()) { // 2.여는 중괄호 다음에 줄 바꿈이 있습니다.
    method();
  } //3. 닫는 중괄호 앞에 줄 바꿈이 있습니다.
};
return new MyClass() {
  @Override public void method() {
    if (condition()) {
      try {
        something();
      } catch (ProblemException e) { // 4. 닫는 중괄호 다음에 줄바꿈이 ... 
        recover();
      }
    } else if (otherCondition()) {
      somethingElse();
    } else {
      lastThing();  
    }
    {   // 5. 예외
      int x = foo();
      frob(x);
    }
  }
};
  • 4.8.1 Enum 클래스 섹션에서는 Enum 클래스에 대한 몇 가지 예외가 설명되어 있습니다.

4.1.3 빈 블록: 간결하게 사용 가능

빈 블록 또는 블록과 유사한 구조는 K & R 스타일(섹션 4.1.2에서 설명한 대로)로 사용할 수 있습니다. 또는 그것은 열리자 마자 바로 닫힐 수 있으며 중간에 문자나 줄 바꿈이 없어야 합니다 ({}), 이것은 다중 블록 문의 일부가 아닌 한 그렇게 사용될 수 있습니다 (여러 블록을 직접 포함하는 것: if/else 또는 try/catch/finally).

  // ⭕
  void doNothing() {}

  // ⭕
  void doNothingElse() {
  }

  // ❌ : 간결한 표현은 다중 블록의 일부에서 사용할 수 없음
  try {
    doSomething();
  } catch (Exception e) {}

4.2 블록 들여쓰기: +2 스페이스

새로운 블록 또는 블록과 유사한 구조가 열릴 때마다 들여쓰기는 2 스페이스씩 증가합니다. 블록이 끝나면 들여쓰기는 이전 들여쓰기 수준으로 돌아갑니다. 들여쓰기 수준은 블록 내의 코드와 주석에 모두 적용됩니다. (4.1.2절 "비어 있지 않은 블록: K & R 스타일"의 예제를 참조하세요.)

✏️개인의견 회사에서 유지보수하는 프로젝트들은 Tab으로 들여쓰기를 해서 이건 적용하기 좀 힘들겠네

// 예시
public void someMethod() {
  // 들여쓰기 2 스페이스로 시작
  if (condition) {
    // 들여쓰기 4 스페이스로 증가
    doSomething();
  } else {
    // 들여쓰기 4 스페이스로 증가
    doSomethingElse();
  }
  // 들여쓰기 2 스페이스로 복귀
}

4.3 한 줄에 하나의 문장

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

4.4 열 제한: 100

자바 코드의 열 제한은 100자입니다. "문자"는 어떤 유니코드 코드 포인트도 의미합니다. 아래에 언급된 것을 제외하고는 이 제한을 초과하는 모든 줄은 4.5절, 줄 바꿈에서 설명한 대로 줄 바꿈해야 합니다.

각 유니코드 코드 포인트는 그 표시 폭이 더 크거나 작더라도 하나의 문자로 계산됩니다.
예를 들어, 전체 폭 문자를 사용하는 경우, 엄격한 필요에 따라 이 규칙보다 일찍 줄 바꿈을 선택할 수 있습니다.

예외 사항:

  1. 열 제한을 준수하는 것이 불가능한 줄 (예: Javadoc의 긴 URL 또는 긴 JSNI 메서드 참조).
  2. 패키지 및 임포트 문 (3.2 패키지 선언 및 3.3 임포트 문 참조).
  3. 복사하여 쉘에 붙여넣을 수 있는 주석 내의 명령 줄.
  4. 아주 긴 식별자는 거의 사용되지 않는 경우에만 열 제한을 초과할 수 있습니다. 이 경우 주변 코드에 대한 유효한 줄 바꿈은 google-java-format이 생성한 것과 같습니다.
  • ✏️개인의견 위 google-java-format을 이클립스에 적용해보자(들여쓰기가 2스페이스인것은 수정해야할듯) >참고링크

4.5 줄 바꿈

용어 참고: 그렇지 않았다면 하나의 줄에 들어갈 수 있는 코드가 여러 줄로 나누어질 때, 이 활동을 줄 바꿈이라고 합니다.

모든 상황에서 정확히 어떻게 줄 바꿈을 해야 하는지를 보여주는 종합적이고 결정적인 공식은 없습니다. 많은 경우 동일한 코드를 여러 가지 유효한 방법으로 줄 바꿈할 수 있습니다.

참고: 줄 바꿈을 하는 주된 이유는 열 제한을 초과하지 않도록 하는 것이지만, 열 제한 내에 맞는 코드조차도 작성자의 재량에 따라 줄 바꿈될 수 있습니다.

: 메서드 또는 지역 변수를 추출하면 줄 바꿈이 필요하지 않은 경우가 있으므로 문제를 해결할 수 있습니다.

4.5.1 줄 바꿈 위치

줄 바꿈의 주된 원칙은 높은 문법적 수준에서 줄 바꿈하는 것을 선호하는 것입니다. 또한 다음 사항에 대해 적용됩니다

  1. 대입 연산자가 아닌 연산자에서 줄 바꿈이 필요한 경우, 해당 기호 앞에서 줄 바꿈이 이루어집니다. (다른 언어인 C++ 및 JavaScript와 달리 사용되는 관행임에 유의하세요.)
    int result = someLongVariable + anotherLongVariable
     + yetAnotherLongVariable; // 기호 앞에서 줄바꿈
  • 이는 다음과 같은 "연산자와 유사한" 기호에도 적용됩니다
    1. 점 구분자 (.)
    2. 메서드 참조의 두 개의 콜론 (::)
    3. 타입 바운드 내에서의 앰퍼샌드 (<T extends Foo & Bar>)
    4. catch 블록에서의 파이프 (catch (FooException | BarException e))
  • ✏️개인의견 무슨소린지 이해가 안된다면 ChatGPT를 사용해봅시다.

  1. 대입 연산자에서 줄 바꿈이 발생하는 경우, 일반적으로 해당 기호 뒤에서 줄 바꿈이 이루어집니다. 그러나 어느 쪽이든 허용됩니다. 이것은 향상된 for("foreach") 문의 "할당 연산자와 유사한" 콜론에도 적용됩니다.
    int variableName =
     someLongExpression;
  2. 메서드 또는 생성자 이름은 그 뒤를 따르는 여는 괄호 (에서 줄바꿈 가능
  3. 쉼표 , 에서 줄바꿈 가능
  4. 람다식의 경우 화살표->에 줄바꿈 가능
    • 그러나 보통 람다식은 줄바꿈이 발생하지 않음.

4.5.2 연속된 줄을 적어도 +4 스페이스로 들여쓰기

줄 바꿈을 할 때, 첫 번째 줄 이후의 각 줄(각 연속 줄)은 원래 줄에서 최소 +4 스페이스로 들여쓰기됩니다.

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

수평 정렬에 관한 4.6.3절 "수평 정렬"은 이전 줄과 일부 토큰을 정렬하기 위해 가변 개수의 스페이스를 사용하는 비권장 관행을 다룹니다.

//예시
void longMethodName(String argument1, String argument2, String argument3,
                    String argument4) { // +4 스페이스 들여쓰기
    ...
}

int[] numbers = {
    1, 2, 3, // +4 스페이스 들여쓰기
    4, 5, 6 // +4 스페이스 들여쓰기
};

List<String> myList = new ArrayList<String>()
    .add("Item 1")  // +4 스페이스 들여쓰기
    .add("Item 2")  // +4 스페이스 들여쓰기
    .add("Item 3"); // +4 스페이스 들여쓰기

4.6 공백

4.6.1 수직 공백(✏️개인의견 : 엔터를 말함)

단일 빈 줄은 항상 다음과 같은 경우에 나타납니다:

  1. 클래스의 연속 멤버 또는 초기화자 사이: 필드, 생성자, 메서드, 중첩 클래스, 정적 초기화자 및 인스턴스 초기화자.
    • 예외: 두 개의 연속 필드 사이에 빈 줄(다른 코드가 사이에 없는 경우)은 선택 사항입니다. 이러한 빈 줄은 필드를 논리적 그룹으로 만들기 위해 필요한 경우에 사용됩니다.
    • 예외: Enum 상수 사이의 빈 줄은 4.8.1절에서 다룹니다.
  2. 이 문서의 다른 섹션(예: 3절 "소스 파일 구조" 및 3.3절 "Import 문")에서 필요한 경우.
    단일 빈 줄은 코드를 논리적 하위 섹션으로 구성하기 위해 문장 사이에 나타날 수도 있습니다. 클래스의 첫 번째 멤버 또는 초기화자 앞에 또는 클래스의 마지막 멤버 또는 초기화자 뒤에 나타나는 빈 줄은 권장되지 않지만 비권장되지도 않습니다.
  • 여러 연속된 빈 줄은 허용되지만 필요하거나 권장되지는 않습니다.

4.6.2 수평 공백(✏️개인의견 : 스페이스를 말함)

  • 언어나 다른 스타일 규칙에서 필요한 경우를 제외하고, 리터럴, 주석 및 Javadoc을 제외하면, 단일 ASCII 스페이스는 다음 위치에서만 사용됩니다.
  1. 예약어(if, for 또는 catch와 같은)와 그 뒤에 나오는 여는 괄호 (()를 분리하는 경우
  2. 예약어(else 또는 catch와 같은)와 그 앞에 나오는 닫는 중괄호 (})를 분리하는 경우
  3. 어떤 여는 중괄호 ({) 앞에 무엇이 오더라도(다음의 두 가지 예외를 제외하고):
    • @SomeAnnotation({a, b}) (스페이스를 사용하지 않음)
    • String[][] x = {{"foo"}}; (아래 항목 9의 {{ 사이에 스페이스가 필요하지 않음)
  4. 이항 또는 삼항 연산자 양쪽에 스페이스가 존재합니다. 이것은 다음과 같은 "연산자와 유사한" 기호에도 적용됩니다:
    • 합동 유형 바운드에서 앰퍼샌드: <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 스타일에서 허용되지만, 필수는 아님. 코드의 가독성을 높이기 위해 필요한 경우에만 사용할 것

// 정렬을 사용하지 않은 예
int x = 100;
String name = "John";

// 정렬을 사용한 예
int    x     = 100;
String name  = "John";

Tip : 정렬은 가독성을 높힐 수 있지만, 향후 유지보수에 문제를 일으킬 수 있음. 단 하나의 줄 만 수정해야 하는 경우에 이전 서식을 망치게 될 수 있어 더 많은 코드 수정이 필요할 수 있다. 최악의 경우에는 무의미안 업무를 초래할 수 있어용.

4.7 그룹화 괄호 : 권장사항

  • 선택적인 그룹화 괄호는 작성자와 리뷰어가 동의하는 경우에만 생략됩니다.
  • 그리고 그렇게 하더라도 코드를 잘못 해석할 가능성이 없거나 코드를 읽기 더 쉽게 만들어 주지 않았다고 판단될 때만 생략됩니다.
  • 모든 독자가 자바 연산자 우선순위 표를 외워 두었다고 가정하는 것은 합리적이지 않습니다.
// 그룹화 (권장)
int result = (x + y) * z;
// 그룹화 X
int result = x + y * z;
  • ✏️개인의견 : 그룹화 괄호를 사용함으로 써 코드를 더 명확하게, 이해하기 쉽게 표시해줌.

4.8 특정 구조체

4.8.1 Enum 클래스

  • 각 쉼표 뒤에 줄바꿈은 선택사항입니다. 추가적인 빈 줄도 허용됩니다.
  • 메서드가 없고, 문서화가(✏️개인의견 주석같은걸 말하는듯) 없는 Enum 클래스는 배열 초기화처럼 한줄에 쓸 수 있음.
    private enum Suit { CLUBS, HEARTS, SPADES, DIAMONDS }
  • Enum클래스는 클래스에 대한 서식 지침이 적용됨.

4.8.2 변수 선언

4.8.2.1 선언당 하나의 변수
  • 모든 변수 선언(필드 또는 지역 변수)은 오직 하나의 변수만 선언합니다. int a, b;와 같은 선언은 사용하지 않습니다.
  • 예외: 여러 변수 선언은 for 루프의 헤더에서 허용됩니다.
4.8.2.2 필요할 때 선언
  • 지역 변수는 일반적으로 그들을 최초로 사용하는 지점 근처에서 (합리적인 범위 내에서) 선언되지 않습니다. 대신, 지역 변수는 일반적으로 초기화값을 가지거나 선언 직후에 즉시 초기화됩니다.

4.8.3 배열

4.8.3.1 배열 초기화자: "블록 형식"일 수 있음
  • 어떤 배열 초기화자든 선택적으로 "블록과 유사한 구조"처럼 서식을 지정할 수 있습니다. 예를 들어, 다음은 모두 유효한 형식입니다
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 스위치 문

용어 참고: 스위치 블록의 중괄호 내부에는 하나 이상의 문 그룹이 있습니다. 각 문 그룹은 하나 이상의 스위치 라벨 (case FOO: 또는 default:)과 하나 이상의 문 (또는 마지막 문 그룹의 경우 제로 이상의 문)으로 구성됩니다.

4.8.4.1 들여쓰기

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

스위치 라벨 뒤에는 줄 바꿈이 오며, 들여쓰기 수준은 마치 블록이 열린 것처럼 +2 증가합니다. 다음 스위치 라벨은 이전 들여쓰기 수준으로 돌아가 마치 블록이 닫힌 것처럼 됩니다.

4.8.4.2 Fall-through: 주석

스위치 블록 내에서 각 문 그룹은 갑작스레 종료(브레이크, 컨티뉴, 리턴 또는 예외 발생)되거나 다음 문 그룹으로 실행이 계속될 수 있음을 나타내는 주석으로 표시됩니다. 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 문 그룹이 포함되어야 합니다.

예외: 열거형(enum) 유형에 대한 스위치 문은 해당 유형의 모든 가능한 값을 다루는 명시적인 케이스를 포함하는 경우 default 문 그룹을 생략할 수 있습니다. 이렇게 하면 IDE 또는 다른 정적 분석 도구가 빠뜨린 케이스가 있는 경우 경고를 발생시킬 수 있습니다.

4.8.5 Annotaions

4.8.5.1 Type-use annotations

type-use annotations은 어노테이션이 달릴 타입 바로 앞에 나타납니다. 어노테이션이 @Target(ElementType.TYPE_USE)로 메타 주석 처리된 경우, 이것은 유형 사용 주석입니다.

@NonNull String name = "John";
//이 경우 String Type의 변수 name이 Null이 되지 않아야함을 나타내는 어노테이션으로 String type 바로 앞에 배치함.
4.8.5.2 Class annotations

클래스 어노테이션은 the documentation block(✏️개인의견 : 주석 /.../) 바로 뒤에 나타나며, 각각의 어노테이션이 자신의 줄을 가지고 있고, 줄바꿈을 하지 않으므로 여러개의 어노테이션을 사용해도 들여쓰기를 하지 않음

4.8.5.3 Method and constructor annotations

4.8.5.2 Class annotations와 동일함

  • 예외적으로 매개변수가 없는 어노테이션은 한줄에 나타낼 수 있음.
    @Override public int hashCode() { ... }
    4.8.5.4 Field annotations

필드에 적용되는 어노테이션은 the documentation block(✏️개인의견 : 주석 /.../) 바로 뒤에 나타나며, 여러 어노테이션을 사용해도 동일한 줄에 나열할 수 있음.

4.8.5.5 Parameter and local variable annotations

Type-use annotations인 경우가 아니라면 규칙 없음

4.8.6 주석

  • 스킵

Any line break may be preceded by arbitrary whitespace followed by an implementation comment. Such a comment renders the line non-blank.

4.8.6.1 Block comment style

Block comments are indented at the same level as the surrounding code. They may be in /* ... / style or // ... style. For multi-line / ... */ comments, subsequent lines must start with * aligned with the * on the previous line.

4.8.7 수식어

다음 순서대로 나타남

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

4.8.8 숫자 리터럴

  • long타입 정수 리터럴은 대문자L을 사용한다. (숫자 1과 혼동을 피하기 위해)
    3000000000L  // O
    3000000000l  // X

5 명명(네이밍)

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

식별자는 ASCII 문자 및 숫자만 사용하며, 아래에 명시된 소수의 경우를 제외하고는 밑줄을 사용하지 않습니다. 따라서 각 유효한 식별자 이름은 정규 표현식 \w+와 일치합니다.

Google 스타일에서는 특별한 접두사 또는 접미사를 사용하지 않습니다. 예를 들어, 다음과 같은 이름은 Google 스타일이 아닙니다: name_, mName, s_name 및 kName.

5.2 식별자 유형별 규칙

5.2.1 패키지 이름

패키지 이름은 소문자와 숫자만 사용하며 (밑줄은 사용하지 않습니다), 연속된 단어는 단순히 연결합니다.

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

5.2.2 클래스 이름

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

  • ✏️개인의견 UpperCamelCase : 항상 식별자의 첫번째 문자는 대문자로 표기 해야 하며, 만약 여러단어가 포함되어 있는 경우라면, 각 단어를 구분짓게 해주기 위해서 마찬가지로 대문자로 표기해야 한다.

클래스 이름은 일반적으로 명사 또는 명사 구문입니다. 예를 들어, Character 또는 ImmutableList와 같습니다. 인터페이스 이름도 명사 또는 명사 구문일 수 있으며 (예: List), 때로는 대신 형용사 또는 형용사 구문일 수도 있습니다 (예: Readable).

테스트 클래스의 이름은 Test로 끝나며, 예를 들어 HashIntegrationTest와 같습니다. 단일 클래스를 다루는 경우 클래스 이름에 Test를 추가하면 됩니다. 예를 들어 HashImplTest와 같습니다.

5.2.3 메서드 이름

메서드 이름은 lowerCamelCase로 작성됩니다.

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

JUnit 테스트 메서드 이름에서는 이름의 논리적 구성 요소를 구분하기 위해 밑줄 (_)을 사용할 수 있으며, 각 구성 요소는 lowerCamelCase로 작성됩니다. 예를 들어 transferMoney_deductsFromSource와 같습니다. 테스트 메서드를 명명하는 정확한 방법은 고정된 것은 없습니다.

5.2.4 상수 이름

상수 이름은 UPPER_SNAKE_CASE를 사용합니다. 즉, 모든 대문자로 표기하고 각 단어를 밑줄 하나로 구분합니다.

5.2.5 비-상수 필드 이름

상수가 아닌 필드 이름(정적 또는 그렇지 않음)은 lowerCamelCase로 작성합니다.

5.2.6 매개변수 이름

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

5.2.7 지역 변수 이름

지역 변수 이름은 lowerCamelCase로 작성합니다.
지역 변수가 final이고 변경할 수 없더라도, 이러한 변수는 상수로 간주되지 않으며 상수로 스타일을 지정해서는 안됩니다.

5.2.8 타입 변수 이름

각 타입 변수는 두 가지 스타일 중 하나로 명명됩니다:

단일 대문자로 시작하고 선택적으로 단일 숫자가 뒤에 올 수 있습니다(예: E, T, X, T2).
클래스에 사용된 형식을 따르는 이름 다음에 대문자 T가 옵니다(예: RequestT, FooBarT).

6 프로그래밍 관행

6.1 @Override: 항상 사용

메서드가 사용 가능한 경우에는 항상 @Override 어노테이션으로 표시됩니다. 이는 슈퍼클래스 메서드를 재정의하는 클래스 메서드, 인터페이스 메서드를 구현하는 클래스 메서드, 그리고 슈퍼인터페이스 메서드를 재지정하는 인터페이스 메서드를 포함합니다.

예외: 부모 메서드가 @Deprecated로 표시된 경우에는 @Override를 생략할 수 있습니다.

6.2 처리된 예외: 무시하지 않음

아래에 설명된 사항을 제외하고는 처리된 예외에 대해 아무런 조치도 취하지 않는 것은 매우 드뭅니다. (일반적으로 예외를 로그에 기록하거나, 예외가 "불가능"한 것으로 간주되면 AssertionError로 다시 던지는 것입니다.)

실제로 catch 블록에서 아무 작업도 수행하지 않는 것이 정당한 경우는 해당 이유가 주석으로 설명되어야 합니다.

6.3 Static 멤버 : 클래스를 사용

정적 클래스 멤버에 대한 참조를 수식해야 할 때 해당 클래스의 이름으로 수식합니다. 해당 클래스의 유형에 대한 참조나 표현식으로는 수식하지 않습니다.

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

6.4 파이널라이저: 사용하지 않음

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

✏️개인의견 : ChatGPT 설명에 따르면...

  • finalize() 메서드를 사용하는 것은 일반적으로 권장되지 않습니다. 대신, 자원 해제나 정리 작업을 직접 수행하는 방법을 고려해야 합니다. finalize()를 사용하는 것은 Java 가비지 컬렉션의 동작을 불필요하게 복잡하게 만들 수 있으며, 예상치 못한 부작용을 일으킬 수 있습니다.

: 그렇게 하지 마십시오. 반드시 해야 하는 경우에는 먼저 Effective Java 아이템 8, "파이널라이저와 클리너 피하기"를 매우 주의 깊게 읽고 이해한 후에도 하지 마십시오.

7. JavaDoc

  • 다음 링크 참고 : https://google.github.io/styleguide/javaguide.html#s7-javadoc

✏️개인의견 : 파트 내에서 관련 내용을 작성중인걸로 알고 있어 패스

 

다른 재미있는 글들도 한번 보고 가세요
 

개발자는 Chat GPT를 어떻게 쓰면 좋을까? - 1 💻

- ▶💻개발자는 Chat GPT를 어떻게 쓰면 좋을까? (1/1) ChatGPT는 현대 개발 프로세스에서 다양한 역할을 수행할 수 있는 강력한 도구로 자리 잡고 있습니다. 이러한 인공 지능 모델은 다양한 측면에

janggiraffe.tistory.com

 

# SpringBoot 서버와 AJAX 통신 시 시간이 이상해요⏰

SpringBoot 서버와 AJAX 통신 시 시간이 이상해요⏰ SpringBoot 2.0 이상에서의 직렬화 처리 - timeStamp 단어 뜻 직렬화 데이터 구조나 오브젝트 상태를 동일하거나 다른 컴퓨터 환경에 저장하고 나중에 재

janggiraffe.tistory.com

 

 

구글 자바 포매터 적용해보기(for eclipse)

구글 자바 포메터 설치(이클립스) 구글 자바 스타일가이드를 번역하면서 해당 포멧에 맞게 자동으로 소스를 변환해주는 플러그인에 대해 알게되서 이번에 적용해보려고 한다. 스타일가이드 : ht

janggiraffe.tistory.com

 

반응형