Skip to content

Java Style Guide

Hoyun Jung edited this page Nov 29, 2025 · 1 revision

1. 파일

  1. 모든 소스, 텍스트 문서 파일의 인코딩은 UTF-8로 통일한다.
  2. Unix 형식의 LF(Line Feed, 0x0A)을 사용한다. Windows 형식인 CRLF가 섞이지 않도록 IDE와 Git 설정 등을 확인한다.

2. 이름 (Naming)

1. 공통

  1. 패키지 이름은 소문자를 사용하여 작성한다. 언더스코어(_)나 대문자를 섞지 않는다.
  2. 변수명, 클래스명, 메서드명 등에는 영어와 숫자만을 사용한다. 상수는 단어 사이의 구분을 위하여 언더스코어(_)를 사용한다.
  3. 식별자의 이름은 한글 발음을 영어로 옮겨서 표기하지 않는다. (한국어 고유명사는 예외)
    • 나쁜 예 : moohyungJasan (무형자산)
    • 좋은 예 : intangibleAssets (무형자산)
  4. 약어의 중간 단어는 소문자로 표기한다.
    • 나쁜 예: HTTPAPIURL
    • 좋은 예: HttpApiUrl

2. 클래스/인터페이스

  1. 클래스/인터페이스의 이름은 단어의 첫 글자를 대문자로 시작하는 대문자 카멜표기법(Upper camel case)을 사용한다.
  2. 클래스 이름은 명사나 명사절로 짓는다.
  3. 테스트 클래스의 이름은 테스트하고자 하는 클래스의 이름에 Test 접미사를 붙여 짓는다.
  4. 인터페이스의 이름은 클래스 이름은 명사/명사절이나 형용사/형용사절로 짓는다.

3. 메서드

  1. 메서드의 이름은 첫 번째 단어를 소문자로 작성하고, 이어지는 단어의 첫 글자를 대문자로 작성하는 소문자 카멜표기법(Lower camel case)를 사용한다. 테스트 클래스의 메서드 이름에서도 마찬가지이다.
  2. 메서드명은 기본적으로 동사로 시작한다. 다른 타입으로 변환하는 메서드나 빌더 패턴을 구현한 클래스의 메서드는 전치사로 시작할 수 있다.
    • 동사 사용 예: renderHtml()
    • 전환 메서드 예: toString()
    • 빌더 패턴 메서드 예: withUserId(String id)

4. 상수/변수

  1. 상수 이름은 대문자로 작성하며, 복합어는 언더스코어(_)를 사용하여 단어를 구분한다.
  2. 상수가 아닌 클래스의 멤버변수/지역변수/메서드 파라미터에는 소문자 카멜표기법(Lower camel case)을 사용한다.
  3. 메서드 블럭 범위 이상의 생명 주기를 가지는 변수에는 한 글자로 된 이름을 쓰지 않는다. 반복문의 인덱스나 람다 표현식의 파라미터 등 짧은 범위의 임시 변수에는 관례적으로 한 글자 변수명을 사용할 수 있다.
    • 나쁜 예: HtmlParser p = new HtmlParser();
    • 좋은 예: HtmlParser parser = new HtmlParser();

3. 선언 (Declarations)

  1. 클래스의 import는 IntelliJ 기본 설정을 따른다.
  2. 탑레벨 클래스(Top level class)는 소스 파일에 1개만 존재해야 한다.
  3. 클래스/메서드/멤버변수 제한자의 순서는 IntelliJ 기본 설정을 따른다.
  4. 클래스, 인터페이스, 메서드, 생성자에 붙는 애노테이션 선언 후 새줄을 사용한다.
  5. 문장이 끝나는 ; 뒤에는 새줄을 삽입한다. 한 줄에 여러 문장을 쓰지 않는다.
  6. 변수 선언문은 한 문장에서 하나의 변수만을 다룬다.
  7. 배열 선언에 오는 대괄호는 타입의 바로 뒤에 붙인다.
    • 나쁜 예: String names[];
    • 좋은 예: String[] names;
  8. long 형의 숫자에는 마지막에 대문자 'L’을 붙인다.
  9. \b\f\n, \r, \t, \\\ 와 같이 특별히 정의된 선언 방식이 있는 특수 문자들은 숫자를 이용한 \008 이나 \u0008와 같은 숫자를 넣은 선언보다 전용 방식을 활용한다.
  10. 읽는 사람이 타입을 쉽게 유추 할 수 있는 지역 변수의 경우에만 var 키워드를 사용할 수 있다.
  11. 로컬 변수나 메서드 파라미터에도 가능한 경우 final 키워드를 사용하여 값의 변경을 방지한다.

4. 들여쓰기 (Indentation)

  1. 들여쓰기는 탭 대신 4개의 스페이스를 사용한다.
  2. 클래스, 메서드, 제어문 등의 코드 블럭이 생길 때마다 1단계를 더 들여쓴다.

5. 중괄호 (Braces)

  1. 중괄호 선언은 K&R 스타일(Kernighan and Ritchie style)을 따른다.

  2. else, catch, finally 키워드는 닫는 중괄호(}) 와 같은 줄에 쓴다.

    • 나쁜 예

      if (line.startWith(WARNING_PREFIX)) {
          return LogPattern.WARN;
      }
      else if (line.startWith(DANGER_PREFIX)) {
          return LogPattern.DANGER;
      }
      else {
          return LogPattern.NORMAL;
      }
    • 좋은 예

      if (line.startWith(WARNING_PREFIX)) {
          return LogPattern.WARN;
      } else if (line.startWith(DANGER_PREFIX)) {
          return LogPattern.NORMAL;
      } else {
          return LogPattern.NORMAL;
      }
  3. 내용이 없는 블럭을 선언할 때는 같은 줄에서 중괄호를 닫는 것을 허용한다.

    • 예: public void close() {}
  4. 조건, 반복문이 한 줄로 끝나더라도 중괄호를 사용한다.

    • 나쁜 예

      if (exp == null) return false;
      
      for (char ch : exp.toCharArray()) if (ch == 0) return false;
    • 좋은 예

      if (exp == null) {
          return false;
      }
      
      for (char ch : exp.toCharArray()) {
          if (ch == 0) {
              return false;
          }
      }

6. 줄바꿈 (Line-wrapping)

  1. 최대 줄 사용 너비는 120자까지 가능하다. 단, package,import 선언문에서는 최대 줄수를 초과하더라도 한 줄로 쓴다.

  2. 가독성을 위해 줄을 바꾸는 위치는 다음 중의 하나로 한다.

    • extends 선언 후, implements 선언 후, throws 선언 후
    • 시작 소괄호(() 선언 후, 콤마(,) 후
    • . 전, 연산자(e.g. +, -, ==, &&, ||, instanceof 등) 전
    public boolen isAbnormalAccess (  // 시작 소괄호 선언 후
        User user,  // 콤마 후
        AccessLog log
    ) {
        String message = user.getId() + "|" | log.getPrefix()  // 연산자 전
            + "|" + SUFFIX;
    }
  3. 스트림(Stream)이나 메서드 체이닝은 체이닝이 2단계 이상이거나, 가독성을 해칠 경우 연산자(메서드)마다 줄을 바꾼다.


7. 빈 줄 (Blank lines)

  1. package 선언 후 빈 줄을 삽입한다.

  2. 메서드의 선언이 끝난 후 다음 메서드 선언이 시작되기 전에 빈줄을 삽입한다.

    public void setId(int id) {
        this.id = id;
    }
    
    public void setName(String name) {
        this.name = name;
    }

8. 공백(Whitespace)

  1. 빈 줄을 포함하여 모든 줄은 탭이나 공백으로 끝내지 않는다.

  2. 여는 중괄호({) 앞에 공백을 삽입한다. 닫는 중괄호(}) 뒤에 else ,catch 등의 키워드가 있을 경우 중괄호와 키워드 사이에 공백을 삽입한다.

    public void printWarnMessage(String line) {
        if (line.startsWith(WARN_PREFIX)) {
            ...
        } else {
            ...
        }
    }
  3. ifforwhilecatchsynchronizedswitch와 같은 제어문 키워드의 뒤에 소괄호((, ))를 선언하는 경우, 시작 소괄호 앞에 공백을 삽입한다.

    if (maxLine > LIMITED) {
        return false;
    }
  4. 생성자와 메서드의 선언, 호출, 애노테이션 선언 뒤에 쓰이는 소괄호(() 사이에는 공백을 삽입하지 않는다.

    • 나쁜 예

      public StringProcessor () {} // 생성자
      
      @Cached ("local")
      public String removeEndingDot (String original) {
          assertNotNull (original);
          ...
      }
    • 좋은 예

      public StringProcessor() {} // 생성자
      
      @Cached("local")
      public String removeEndingDot(String original) {
          assertNotNull(original);
          ...
      }
  5. 타입 캐스팅을 위해 선언한 소괄호의 내부에는 공백을 삽입하지 않는다.

    • 나쁜 예: String message = ( String ) rawLine;
    • 좋은 예: String message = (String)rawLine;
  6. 제네릭(Generics) 선언에 쓰이는 산괄호(<,>) 주위의 공백은 다음과 같이 처리한다.

    1. 제네릭 메서드 선언 일 때만 < 앞에 공백을 삽입한다.
    2. < 뒤에 공백을 삽입하지 않는다.
    3. > 앞에 공백을 삽입하지 않는다.
    4. 아래의 경우를 제외하고는 >뒤에 공백을 삽입한다.
      • 메서드 레퍼런스가 바로 이어질 때
      • 여는 소괄호(()가 바로 이어질 때
      • 메서드 이름이 바로 이어질 때
    public static <A extends Annotation> A find(AnnotatedElement elem, Class<A> type) {
        List<Integer> l1 = new ArrayList<>();  // '(' 가 바로 이어질때
        List<String> l2 = ImmutableList.Builder<String>::new;  // 메서드 레퍼런스가 바로 이어질 때
        int diff = Util.<Integer, String>compare(l1, l2);  // 메서드 이름이 바로 이어질 때
    }
  7. 콤마(,)와 반복문(while, for)의 구분자로 쓰이는 세미콜론(;)의 뒤에 공백을 삽입한다.

    • 나쁜 예

      for (int i = 0;i < length;i++) {
          display(level,message,i)
      }
    • 좋은 예

      for (int i = 0; i < length; i++) {
          display(level, message, i)
      }
  8. 반복문과 삼항연산자의 콜론(:) 앞 뒤에 공백을 삽입한다. 단, 라벨 선언의 앞 뒤에는 공백을 삽입하지 않는다.

    for (Customer customer : visitedCustomers) {
        AccessPattern pattern = isAbnormal(accessLog) ? AccessPattern.ABUSE : AccessPattern.NORMAL;
        int grade = evaluate(customer, pattern);
    
        switch (grade) {
            case GOLD:
                sendSms(customer);
            case SILVER:
                sendEmail(customer);
            default:
                inreasePoint(customer)
        }
    }
  9. 이항/삼항 연산자의 앞 뒤에는 공백을 삽입한다.

  10. 단항 연산자와 연산 대상의 사이에는 공백을 삽입하지 않는다.

  11. 주석의 전후에는 아래와 같이 공백을 삽입한다.

    1. 명령문과 같은 줄에 주석을 붙일 때 // 앞
    2. 주석 시작 기호 // 뒤
    3. 주석 시작 기호 /* 뒤
    4. 블록 주석을 한 줄로 작성시 종료 기호 / 앞
    /*
     * 공백 후 주석내용 시작
     */
    
    System.out.print(true);  // 주석 기호 앞 뒤로 공백
    
    /* 주석내용 앞에 공백, 뒤에도 공백 */

참고 자료

Clone this wiki locally