Google Java Style Guide와 Oracle 코딩 컨벤션의 차이를 비교하고, 팀에서 실제로 “지켜지는” Java 컨벤션을 만드는 방법과 자동화(Formatter/Checkstyle) 예제를 정리합니다.
도입 (문제 상황)
리뷰에서 “이건 제 스타일이랑 달라요” 같은 코멘트가 반복되면, 코드 품질보다 표기 방식이 논쟁의 중심이 되기 쉽습니다. 더 큰 문제는 프로젝트가 커질수록 파일마다 들쭉날쭉한 스타일이 쌓여서, 수정 범위가 커지고 히스토리도 지저분해진다는 점입니다. 이럴 때 필요한 게 “누가 봐도 납득 가능한 기준”과 “자동으로 강제되는 도구”예요.
핵심 개념: Google/Oracle 가이드 비교와 “지켜지는” 팀 컨벤션 만들기

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단계를 추천합니다.
- 기반 선택: Google 또는 기존 레거시(사실상 Oracle 관례 포함)를 베이스로 정합니다.
- 예외만 추가: “우리 팀은 여기만 다르게”를 최소화합니다. 예외가 많을수록 도구 적용이 어려워져요.
- 자동화로 강제: 저장 시 포맷(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
'JAVA' 카테고리의 다른 글
| Java 다음 단계로 — Spring과 JVM 생태계 로드맵 (Spring Boot 입문·JVM 튜닝 기초) (0) | 2026.03.04 |
|---|---|
| Java 자주 하는 실수 TOP 10 — NullPointerException부터 리소스 누수까지 실무 트러블슈팅 (0) | 2026.03.03 |
| Java 클린 코드 실천 가이드: 네이밍부터 코드 리뷰 체크리스트까지 (0) | 2026.03.02 |
| Java 의존성 관리 — Maven & Gradle 핵심 (충돌 해결과 멀티 모듈 기초) (1) | 2026.03.02 |
| Java 성능 체크리스트: String 연결부터 메모리 누수 패턴까지 (0) | 2026.03.01 |