우테코 프리코스를 진행하면서 기왕이면 스타일 방식까지 제대로 해보고 싶어서 정리한다.
다른 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. 소스 파일 구조
구성 순서
- 라이센스 or 저작권 정보 ( 존재한다면)
- 패캐지 구문
- import 구문
- 하나의 최상위 클래스
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. 줄 바꿈 : 하나의 줄 -> 여러 줄
열 제한을 넘지 않게 하기 위해 줄 바꿈을 한다. 다만 열 제한이 아니여도 작성자의 재량에 따라 줄 바꿈 가능
줄 바꿈대신 메서드나 지역 변수를 사용하여 대신할 수 있다.
줄 바꿈 규칙
- Non-assignment연산자에서의 줄 바꿈 : 기호 이전에 줄 바꾼다
- dot separator(.)
- two colons (::)
- An ampersand in a type bound ( <>)
- catch 블럭 : catch(Exception)
- assignment(대입) 연산자에서 줄이 끊어지면 일반적으로는 기호 뒤에 오지만 어느 쪽이든 허용
- 메서드나 생성자 뒤에 오는 여는 괄호가 있을때, 콤마 앞에 오는 토큰은 연결되어 있어야 한다.
- 람다식의 인접한 화살표에서는 안바뀌지면 한줄이면 변경 가능
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. 수평 공백
- 예약어 분리 : if, for, catch 같은 예약어 후 여는 괄호에서 사용
- if (), for (), catch (),
- 예약어 분리 : else, catch 같은 예약어 후 닫는 괄호에서 사용
- } else {, } catch [
- 배열 선언문에서는 공백 상관 없음
- 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
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