JAVA

Java 코딩 컨벤션 정리: Google/Oracle 스타일 가이드 비교와 팀 컨벤션 만드는 법

IT Lab 2026. 3. 3. 10:00

Google Java Style Guide와 Oracle 코딩 컨벤션의 차이를 비교하고, 팀에서 실제로 “지켜지는” Java 컨벤션을 만드는 방법과 자동화(Formatter/Checkstyle) 예제를 정리합니다.

도입 (문제 상황)

리뷰에서 “이건 제 스타일이랑 달라요” 같은 코멘트가 반복되면, 코드 품질보다 표기 방식이 논쟁의 중심이 되기 쉽습니다. 더 큰 문제는 프로젝트가 커질수록 파일마다 들쭉날쭉한 스타일이 쌓여서, 수정 범위가 커지고 히스토리도 지저분해진다는 점입니다. 이럴 때 필요한 게 “누가 봐도 납득 가능한 기준”과 “자동으로 강제되는 도구”예요.

핵심 개념: Google/Oracle 가이드 비교와 “지켜지는” 팀 컨벤션 만들기

팀 코딩 컨벤션이 합의에서 자동 포맷과 CI 검사로 이어지는 흐름도

Java 코딩 컨벤션은 단순히 보기 좋게 꾸미는 규칙이 아닙니다. 변경(diff) 최소화, 리뷰 비용 절감, 버그 탐지(일관된 패턴), 온보딩 속도에 직접 영향을 줍니다. 비유하자면, 컨벤션은 “문서 서식”이 아니라 “공통 언어”에 가깝습니다. 말투가 통일되면 내용(로직)에 집중할 수 있듯이요.

Google vs Oracle: 무엇이 다르고 뭘 선택해야 할까요?

Oracle의 “Code Conventions for the Java Programming Language”는 역사적으로 널리 쓰였지만, 문서 자체가 오래된 편이고(현대 도구 체계와의 연결이 약함), 실제 현업에서는 Google 스타일을 기반으로 자동 포매터 + 정적 분석까지 묶어 쓰는 경우가 많습니다. 다만 팀/레거시 상황에 따라 Oracle 관례를 일부 유지하는 게 더 현실적일 때도 있어요.

아래 표는 실무에서 자주 부딪히는 차이를 중심으로 정리했습니다.

항목 Google Java Style Oracle Java Conventions(고전 문서) 실무 선택 가이드
들여쓰기 2 spaces 보통 4 spaces 관례가 많음 기존 코드가 4라면 4 유지가 비용 절감
최대 줄 길이 100 columns 80 columns(전통적 권장) 100이 현실적(IDE/모니터)인 경우 많음
중괄호 스타일 K&R(같은 줄) + 일관된 블록 규칙 K&R 기반이지만 세부 규칙은 팀마다 다양 포매터로 강제 가능한 쪽이 유리
import 정렬 그룹/정렬 규칙이 명확 관례 수준(툴 강제 약함) IDE/formatter와 맞추기 쉬운 규칙 채택
자동화 친화성 Spotless/Checkstyle 등과 결합 쉬움 문서 중심, 자동화 연결은 별도 설계 필요 “규칙+도구” 패키지로 운영 권장
최신 Java(17/21) 대응 커뮤니티에서 지속적으로 적용/확장 문서가 오래되어 직접 해석 필요 최신 문법(Record, Sealed 등)까지 고려해야 함

핵심은 “Google이 무조건 정답”이 아니라, 팀이 합의하고 도구로 강제할 수 있는가입니다. 컨벤션이 문서로만 존재하면, 결국 리뷰에서 사람마다 다른 잣대가 나오고 다시 원점으로 돌아가요.

팀 컨벤션은 이렇게 만드세요: “문서 1장 + 자동화”가 정답에 가깝습니다

팀 컨벤션을 만들 때는 범위를 과하게 넓히지 않는 게 중요합니다. 다음 3단계를 추천합니다.

  1. 기반 선택: Google 또는 기존 레거시(사실상 Oracle 관례 포함)를 베이스로 정합니다.
  2. 예외만 추가: “우리 팀은 여기만 다르게”를 최소화합니다. 예외가 많을수록 도구 적용이 어려워져요.
  3. 자동화로 강제: 저장 시 포맷(Formatter), CI에서 규칙 검사(Checkstyle/SpotBugs 등)로 마무리합니다.

특히 “자동 포맷”은 논쟁을 끝내는 가장 강력한 장치입니다. 사람이 스타일을 판단하지 않아도 되니까요.

flowchart TD
  A[""팀 합의"""] --> B[""베이스 선택 (Google/Legacy)"""]
  B --> C[""예외 규칙 최소화"""]
  C --> D[""자동 포맷 적용 (IDE/Spotless)"""]
  D --> E[""CI에서 스타일 검사 (Checkstyle)"""]
  E --> F[""리뷰는 로직/설계에 집중"""]

팀 컨벤션이 “문서”에서 끝나지 않고 “도구”로 이어지는 흐름을 보여주는 다이어그램입니다.

코드 예제: Google 스타일 기반 + 팀 규칙을 Checkstyle로 강제하기

아래 예제는 복붙해서 바로 실행 가능한 형태로 구성했습니다.

  • App.java: 일부러 컨벤션 위반(줄 길이, 와일드카드 import 등)을 섞어둔 샘플
  • checkstyle.xml: Google 스타일을 참고한 “팀 룰” 예시(필수만 넣고 가볍게)
  • pom.xml: Maven에서 Checkstyle을 실행하는 설정

실행 방법: mvn -q test 또는 mvn -q checkstyle:check
(Maven이 설치되어 있어야 합니다)

1) pom.xml

<!-- pom.xml -->
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.example</groupId>
  <artifactId>java-convention-demo</artifactId>
  <version>1.0.0</version>

  <properties>
    <maven.compiler.release>17</maven.compiler.release>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <checkstyle.version>10.17.0</checkstyle.version>
  </properties>

  <build>
    <plugins>
      <!-- 컴파일러 -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.12.1</version>
        <configuration>
          <release>${maven.compiler.release}</release>
        </configuration>
      </plugin>

      <!-- Checkstyle: CI에서 컨벤션 위반을 실패로 처리 -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-checkstyle-plugin</artifactId>
        <version>3.3.1</version>
        <configuration>
          <configLocation>checkstyle.xml</configLocation>
          <encoding>${project.build.sourceEncoding}</encoding>
          <consoleOutput>true</consoleOutput>
          <failsOnError>true</failsOnError>
          <includeTestSourceDirectory>true</includeTestSourceDirectory>
        </configuration>
        <executions>
          <execution>
            <phase>verify</phase>
            <goals>
              <goal>check</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

2) checkstyle.xml (팀 컨벤션 최소 세트)

<!-- checkstyle.xml -->
<!DOCTYPE module PUBLIC
    "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
    "https://checkstyle.org/dtds/configuration_1_3.dtd">

<module name="Checker">
  <property name="charset" value="UTF-8"/>

  <!-- 파일 공통 규칙 -->
  <module name="LineLength">
    <property name="max" value="100"/>
    <property name="ignorePattern" value="^package.*|^import.*|http(s)?://.*"/>
  </module>

  <module name="TreeWalker">
    <!-- import 관련 -->
    <module name="AvoidStarImport"/>
    <module name="UnusedImports"/>

    <!-- 중괄호/블록 -->
    <module name="NeedBraces"/>
    <module name="LeftCurly"/>
    <module name="RightCurly"/>

    <!-- 네이밍: 팀에서 특히 효과가 큰 규칙 -->
    <module name="MethodName"/>
    <module name="LocalVariableName"/>
    <module name="MemberName"/>

    <!-- 흔한 실수 방지 -->
    <module name="MissingSwitchDefault"/>
  </module>
</module>

3) App.java (위반 예시 포함)

// src/main/java/com/example/App.java
package com.example;

import java.util.*; // AvoidStarImport 위반 예시

public class App {

    private final int userID = 1; // MemberName(카멜케이스) 위반 예시

    public static void main(String[] args) {
        var app = new App();
        System.out.println(app.formatUserMessage("Kim", 3));
    }

    String formatUserMessage(String name, int count) {
        // LineLength(100) 위반 예시: 일부러 길게 작성
        String message = "Hello " + name + ", you have " + count + " new messages. Please check your inbox and respond if needed.";
        
        // NeedBraces 위반 예시
        if (count > 0) System.out.println(message);

        // MissingSwitchDefault 위반 예시
        switch (count) {
            case 1 -> System.out.println("single");
            case 2 -> System.out.println("double");
        }

        return message;
    }
}

이 예제의 포인트는 “컨벤션이 애매한 리뷰 코멘트”가 아니라, 빌드 실패라는 명확한 피드백으로 바뀐다는 점입니다. 스타일 논쟁이 줄어들고, 리뷰는 로직/성능/설계에 집중하기 쉬워져요.

실무 팁

💡 실무에서는: “컨벤션 문서”를 길게 쓰기보다, formatter 설정 파일 + checkstyle 규칙을 저장소에 같이 두는 방식이 유지보수에 유리합니다.

  • 문서는 1페이지(예: CONTRIBUTING.md) 정도로 “기준(베이스) + 예외 3개 이내 + 실행 방법”만 남겨보세요.
  • 새로 합류한 사람이 로컬에서 mvn verify 한 번 돌려보고 바로 감을 잡을 수 있습니다.

💡 실무에서는: 대규모 레거시에 컨벤션을 한 번에 적용하면 “스타일 변경 커밋”이 폭발합니다.

  • 우선 신규/변경 파일부터 적용하고, 기존 파일은 점진적으로 정리하는 편이 안전합니다.
  • 스타일 정리 커밋은 기능 커밋과 분리해 두면, blame/리뷰/릴리즈 관리가 훨씬 편해집니다.

핵심 요약

  • 컨벤션은 미관보다 “리뷰 비용과 변경(diff) 최소화”를 위한 공통 언어입니다.
  • Google/Oracle 중 무엇을 고르든, 예외를 줄이고 도구로 강제해야 실제로 지켜집니다.
  • Formatter(로컬) + Checkstyle(CI) 조합이 가장 현실적인 운영 방식입니다.

다음 글: #39 자주 하는 실수 TOP 10