-
Notifications
You must be signed in to change notification settings - Fork 0
Java Style Guide
- 모든 소스, 텍스트 문서 파일의 인코딩은 UTF-8로 통일한다.
- Unix 형식의 LF(Line Feed, 0x0A)을 사용한다. Windows 형식인 CRLF가 섞이지 않도록 IDE와 Git 설정 등을 확인한다.
- 패키지 이름은 소문자를 사용하여 작성한다. 언더스코어(
_)나 대문자를 섞지 않는다. - 변수명, 클래스명, 메서드명 등에는 영어와 숫자만을 사용한다. 상수는 단어 사이의 구분을 위하여 언더스코어(
_)를 사용한다. - 식별자의 이름은 한글 발음을 영어로 옮겨서 표기하지 않는다. (한국어 고유명사는 예외)
- 나쁜 예 :
moohyungJasan(무형자산) - 좋은 예 :
intangibleAssets(무형자산)
- 나쁜 예 :
- 약어의 중간 단어는 소문자로 표기한다.
- 나쁜 예:
HTTPAPIURL - 좋은 예:
HttpApiUrl
- 나쁜 예:
- 클래스/인터페이스의 이름은 단어의 첫 글자를 대문자로 시작하는 대문자 카멜표기법(Upper camel case)을 사용한다.
- 클래스 이름은 명사나 명사절로 짓는다.
- 테스트 클래스의 이름은 테스트하고자 하는 클래스의 이름에
Test접미사를 붙여 짓는다. - 인터페이스의 이름은 클래스 이름은 명사/명사절이나 형용사/형용사절로 짓는다.
- 메서드의 이름은 첫 번째 단어를 소문자로 작성하고, 이어지는 단어의 첫 글자를 대문자로 작성하는 소문자 카멜표기법(Lower camel case)를 사용한다. 테스트 클래스의 메서드 이름에서도 마찬가지이다.
- 메서드명은 기본적으로 동사로 시작한다. 다른 타입으로 변환하는 메서드나 빌더 패턴을 구현한 클래스의 메서드는 전치사로 시작할 수 있다.
- 동사 사용 예:
renderHtml() - 전환 메서드 예:
toString() - 빌더 패턴 메서드 예:
withUserId(String id)
- 동사 사용 예:
- 상수 이름은 대문자로 작성하며, 복합어는 언더스코어(
_)를 사용하여 단어를 구분한다. - 상수가 아닌 클래스의 멤버변수/지역변수/메서드 파라미터에는 소문자 카멜표기법(Lower camel case)을 사용한다.
- 메서드 블럭 범위 이상의 생명 주기를 가지는 변수에는 한 글자로 된 이름을 쓰지 않는다. 반복문의 인덱스나 람다 표현식의 파라미터 등 짧은 범위의 임시 변수에는 관례적으로 한 글자 변수명을 사용할 수 있다.
- 나쁜 예:
HtmlParser p = new HtmlParser(); - 좋은 예:
HtmlParser parser = new HtmlParser();
- 나쁜 예:
- 클래스의
import는 IntelliJ 기본 설정을 따른다. - 탑레벨 클래스(Top level class)는 소스 파일에 1개만 존재해야 한다.
- 클래스/메서드/멤버변수 제한자의 순서는 IntelliJ 기본 설정을 따른다.
- 클래스, 인터페이스, 메서드, 생성자에 붙는 애노테이션 선언 후 새줄을 사용한다.
- 문장이 끝나는
;뒤에는 새줄을 삽입한다. 한 줄에 여러 문장을 쓰지 않는다. - 변수 선언문은 한 문장에서 하나의 변수만을 다룬다.
- 배열 선언에 오는 대괄호는 타입의 바로 뒤에 붙인다.
- 나쁜 예:
String names[]; - 좋은 예:
String[] names;
- 나쁜 예:
-
long형의 숫자에는 마지막에 대문자 'L’을 붙인다. -
\b,\f,\n,\r,\t,\,\\와 같이 특별히 정의된 선언 방식이 있는 특수 문자들은 숫자를 이용한\008이나\u0008와 같은 숫자를 넣은 선언보다 전용 방식을 활용한다. - 읽는 사람이 타입을 쉽게 유추 할 수 있는 지역 변수의 경우에만
var키워드를 사용할 수 있다. - 로컬 변수나 메서드 파라미터에도 가능한 경우
final키워드를 사용하여 값의 변경을 방지한다.
- 들여쓰기는 탭 대신 4개의 스페이스를 사용한다.
- 클래스, 메서드, 제어문 등의 코드 블럭이 생길 때마다 1단계를 더 들여쓴다.
-
중괄호 선언은 K&R 스타일(Kernighan and Ritchie style)을 따른다.
-
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; }
-
-
내용이 없는 블럭을 선언할 때는 같은 줄에서 중괄호를 닫는 것을 허용한다.
- 예:
public void close() {}
- 예:
-
조건, 반복문이 한 줄로 끝나더라도 중괄호를 사용한다.
-
나쁜 예
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; } }
-
-
최대 줄 사용 너비는 120자까지 가능하다. 단,
package,import선언문에서는 최대 줄수를 초과하더라도 한 줄로 쓴다. -
가독성을 위해 줄을 바꾸는 위치는 다음 중의 하나로 한다.
-
extends선언 후,implements선언 후,throws선언 후 - 시작 소괄호(
() 선언 후, 콤마(,) 후 -
.전, 연산자(e.g.+,-,==,&&,||,instanceof등) 전
public boolen isAbnormalAccess ( // 시작 소괄호 선언 후 User user, // 콤마 후 AccessLog log ) { String message = user.getId() + "|" | log.getPrefix() // 연산자 전 + "|" + SUFFIX; }
-
-
스트림(Stream)이나 메서드 체이닝은 체이닝이 2단계 이상이거나, 가독성을 해칠 경우 연산자(메서드)마다 줄을 바꾼다.
-
package선언 후 빈 줄을 삽입한다. -
메서드의 선언이 끝난 후 다음 메서드 선언이 시작되기 전에 빈줄을 삽입한다.
public void setId(int id) { this.id = id; } public void setName(String name) { this.name = name; }
-
빈 줄을 포함하여 모든 줄은 탭이나 공백으로 끝내지 않는다.
-
여는 중괄호(
{) 앞에 공백을 삽입한다. 닫는 중괄호(}) 뒤에else,catch등의 키워드가 있을 경우 중괄호와 키워드 사이에 공백을 삽입한다.public void printWarnMessage(String line) { if (line.startsWith(WARN_PREFIX)) { ... } else { ... } }
-
if,for,while,catch,synchronized,switch와 같은 제어문 키워드의 뒤에 소괄호((,))를 선언하는 경우, 시작 소괄호 앞에 공백을 삽입한다.if (maxLine > LIMITED) { return false; }
-
생성자와 메서드의 선언, 호출, 애노테이션 선언 뒤에 쓰이는 소괄호(
() 사이에는 공백을 삽입하지 않는다.-
나쁜 예
public StringProcessor () {} // 생성자 @Cached ("local") public String removeEndingDot (String original) { assertNotNull (original); ... }
-
좋은 예
public StringProcessor() {} // 생성자 @Cached("local") public String removeEndingDot(String original) { assertNotNull(original); ... }
-
-
타입 캐스팅을 위해 선언한 소괄호의 내부에는 공백을 삽입하지 않는다.
- 나쁜 예:
String message = ( String ) rawLine; - 좋은 예:
String message = (String)rawLine;
- 나쁜 예:
-
제네릭(Generics) 선언에 쓰이는 산괄호(
<,>) 주위의 공백은 다음과 같이 처리한다.- 제네릭 메서드 선언 일 때만
<앞에 공백을 삽입한다. -
<뒤에 공백을 삽입하지 않는다. -
>앞에 공백을 삽입하지 않는다. - 아래의 경우를 제외하고는
>뒤에 공백을 삽입한다.- 메서드 레퍼런스가 바로 이어질 때
- 여는 소괄호(
()가 바로 이어질 때 - 메서드 이름이 바로 이어질 때
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); // 메서드 이름이 바로 이어질 때 }
- 제네릭 메서드 선언 일 때만
-
콤마(
,)와 반복문(while,for)의 구분자로 쓰이는 세미콜론(;)의 뒤에 공백을 삽입한다.-
나쁜 예
for (int i = 0;i < length;i++) { display(level,message,i) }
-
좋은 예
for (int i = 0; i < length; i++) { display(level, message, i) }
-
-
반복문과 삼항연산자의 콜론(
:) 앞 뒤에 공백을 삽입한다. 단, 라벨 선언의 앞 뒤에는 공백을 삽입하지 않는다.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) } }
-
이항/삼항 연산자의 앞 뒤에는 공백을 삽입한다.
-
단항 연산자와 연산 대상의 사이에는 공백을 삽입하지 않는다.
-
주석의 전후에는 아래와 같이 공백을 삽입한다.
- 명령문과 같은 줄에 주석을 붙일 때
//앞 - 주석 시작 기호
//뒤 - 주석 시작 기호
/*뒤 - 블록 주석을 한 줄로 작성시 종료 기호
/앞
/* * 공백 후 주석내용 시작 */ System.out.print(true); // 주석 기호 앞 뒤로 공백 /* 주석내용 앞에 공백, 뒤에도 공백 */
- 명령문과 같은 줄에 주석을 붙일 때