Hello GH
Google Java Coding Guide 본문
자바 코딩 가이드(By Google)
파일 형태 | 확장자 |
자바 소스 | .java |
자바 바이트코드 | .class |
파일 이름 | 사용 |
GNUmakefile | make파일 이름으로 사용. 소프트웨어를 빌드할 때는 gnumake 명령어를 사용. |
README | 특정 디렉토리의 내용을 요약하는 파일 이름으로 사용. |
▷시작 주석
▷Package문과 Import 문
▷클래스와 인터페이스 선언
/*
* 클래스 이름
*
* 버전 정보
*
* 날짜
*
* 저작권 주의
*/
package java.awt;
import java.awt.peer.CanvasPeer;
Package는 한 번만 선언되어야 한다.
package 이름의 첫번째 부분은 모두 소문자 ASCII 문자를 사용해야 한다.
첫번째 레벨의 도메인 이름들(com, edu, gov, mil, net, org)중에 하나이거나,
1981년 ISO Standard 3166에서 정의된 영어 두 문자로 표현되는 나라 구별 코드 중에 하나이어야 한다.
클래스/인터페이스 선언의 구성요소 | 설명 | |
1 | 클래스/인터페이스 문서화 주석 (/**...*/) | 5) 주석 → 문서화(Documentation) 주석을 참고. |
2 | 클래스/인터페이스 문 | |
3 | 필요할 경우, 클래스/인터페이스 구현 주석 (/*...*/), | 이 주석은 클래스/인터페이스 문서화 주석에 적합하지 않은 하나의 클래스/인터페이스에만 해당하는 정보들을 포함해야 한다. |
4 | 클래스(static) 변수 | 첫번째로는 public 클래스 변수들이 나오고, 그 다음에 protected 클래스 변수들, 그 다음에 package(접근 제한자(access modifier)가 없는 경우) 클래스 변수들, 그 다음에 private 클래스 변수들이 나온다. |
5 | 일반 변수 | 작성하는 순서는 클래스 변수와 동일하다. |
6 | 생성자 | |
7 | 메서드 | 메서드들은 범위나 접근성을 기준으로 나누기 보다는 기능성에 의해서 구성되어야 한다. 예를 들어, private 클래스 메서드가 두 개의 public 메서드들 사이에 존재할 수도 있다. 이렇게 하는 목적은 코드가 더 쉽게 읽히고, 더 쉽게 이해되도록 돕기 위해서이다. |
▷ 연산자(operator) 앞에서 두 줄로 나눈다.
▷ 레벨이 낮은 원칙 보다는 레벨이 높은 원칙에 따라 두 줄로 나눈다.
▷ 앞줄과 같은 레벨의 식(expression)이 시작되는 새로운 줄은 앞줄과 들여쓰기를 일치시킨다.
▷ 만약 위의 원칙들이 코드를 더 복잡하게 하거나 오른쪽 끝을 넘어간다면, 대신에 8개의 빈 칸을 사용해 들여쓴다.
someMethod(longExpression1, longExpression2, longExpression3,
longExpression4, longExpression5);
var = someMethod1(longExpression1,
someMethod2(longExpression2,
longExpression3));
// 괄호로 싸여진 표현식 밖에서 줄 바꿈이 일어나고 더 높은 레벨이기 때문에 될 수 있으면 이 방법을 사용
longName1 = longName2 * (longName3 + longName4 - longName5)
+ 4 * longname6;
// 될 수 있으면 피하는방법
longName1 = longName2 * (longName3 + longName4
- longName5) + 4 * longname6;
// 일반적인 들여쓰기
someMethod(int anArg, Object anotherArg, String yetAnotherArg,
Object andStillAnother) {
...
}
// 너무 멀리 들여쓰는 것을 피하기 위해 8개의 빈 칸으로 들여쓰기
private static synchronized horkingLongMethodName(int anArg,
Object anotherArg, String yetAnotherArg,
Object andStillAnother) {
...
}
- 메서드 본문과 구분하기 위해서 줄을 나누는 경우의 들여쓰기는 일반적으로 8개의 빈 칸 원칙을 사용
// 아래와 같은 들여쓰기는 사용하지 않는 것이 좋다.
if ((condition1 && condition2)
|| (condition3 && condition4)
||!(condition5 && condition6)) { // 좋지 않은 들여쓰기
doSomethingAboutIt(); // 메서드 본문 시작이 명확하지가 않다.
}
// 대신에 아래와 같은 들여쓰기를 사용한다.
if ((condition1 && condition2)
|| (condition3 && condition4)
||!(condition5 && condition6)) {
doSomethingAboutIt();
}
// 또는 아래와 같은 들여쓰기를 사용한다.
if ((condition1 && condition2) || (condition3 && condition4)
||!(condition5 && condition6)) {
doSomethingAboutIt();
}
alpha = (aLongBooleanExpression) ? beta : gamma;
alpha = (aLongBooleanExpression) ? beta
: gamma;
alpha = (aLongBooleanExpression)
? beta
: gamma;
▷ 블록 주석은 파일, 메서드, 자료 구조, 알고리즘에 대한 설명을 제공할 때 사용
▷ 블록 주석은 각각의 파일이 시작될 때와 메서드 전에 사용
▷ 메서드 안에서와 같이 다른 장소에서 사용될 수도 있다.
▷ 메서드 안에 존재하는 블록 주석은 주석이 설명하는 코드와 같은 단위로 들여쓰기를 해야 한다.
ex) 블록 주석은 다른 코드들과 구분하기 위해서 처음 한 줄은 비우고 사용
/*
* 블록 주석 작성
*/
ex) 블록 주석의 들여쓰기를 다시 고치지 못하도록 하기 위한 특별한 블록 주석은 /*- 으로 시작할 수 있다.
/*-
* 여기에 들여쓰기를 무시하는 특별한 블록 주석을 작성한다.
*
* one
* two
* three
*/
▷ 짧은 주석은 뒤따라 오는 코드와 같은 동일한 들여쓰기를 하는 한 줄로 작성할 수 있다.
▷ 만약 주석이 한 줄에 다 들어가지 않는다면, 블록 주석 형식을 따라야 한다.
▷ 한 줄 주석은 빈 줄로 시작되어야 한다.
ex) 자바 코드에서 한 줄 주석의 예제
if (condition) {
/* 이 조건을 만족하면 실행된다. */
...
}
▷ 아주 짧은 주석이 필요한 경우 주석이 설명하는 코드와 같은 줄에 작성
▷ 실제 코드와는 구분될 수 있도록 충분히 멀리 떨어뜨려야 한다.
ex) 자바 코드에서 꼬리 주석을 사용하는 예제
if (a == 2) {
return TRUE; /* 특별한 경우 */
} else {
return isPrime(a); /* a 가 홀수인 경우 */
}
▷ 주석 기호 // 는 한 줄 모두를 주석 처리하거나 한 줄의 일부분을 주석 처리해야 할 때 사용할 수 있다.
▷ 긴 내용을 주석에 포함하기 위해서 연속되는 여러 줄에 이 주석을 사용하는 것은 금지
▷ 어떤 코드의 일부분을 주석 처리하기 위해서 여러 줄에 연속해서 사용하는 것은 허락된다.
ex) 줄 끝 주석을 사용하는 세가지 스타일
if (foo > 1) {
// double-flip을 실행한다.
...
}
else {
return false; // 이유를 여기에 설명한다.
}
//if (bar > 1) {
//
// // double-flip을 실행한다.
// ...
// }
//else {
// return false;
//}
/**
* Example 클래스는 ...
*/
public class Example { ...
ex) 좋은 방법
int level; // 들여쓰기 단위
int size; // 테이블 크기
int level, size //비추
ex) int foo, fooarray[]; //절대 이렇게 사용하지 말자!
int level; // 들여쓰기 단위
int size; // 테이블 크기
Object currentEntry; // 테이블에서 현재 선택된 데이터
ex) 보통 블록은 중괄호인 "{" 과 "}"로 둘러싸인 코드를 이야기한다.
: 부주의한 프로그래머들을 혼돈에 빠뜨릴 수 있고, 영역내에서 코드를 이동해야 하는 경우에 문제를 야기시킬 수 있다.
ex)
void myMethod() {
int int1 = 0; // 메서드 블록의 시작
if (condition) {
int int2 = 0; // "if" 블록의 시작
...
}
}
ex) for 문에서 선언하는 반복문을 위한 인덱스
for (int i = 0; i < maxLoops; i++) { ... }
ex) 블록 안의 블록에서 동일한 변수 이름을 사용해서 선언하지 말아야 함.
int count;
...
myMethod() {
if (condition) {
int count = 0; // 이렇게 사용하지 말 것!
...
}
...
}
▷ 메서드 이름과 그 메서드의 파라미터 리스트의 시작인 괄호 "(" 사이에는 빈 공간이 없어야 한다.
▷ 여는 중괄호 "{" 는 클래스/인터페이스/메서드 선언과 동일한 줄의 끝에 사용
▷ 닫는 중괄호 "}" 는 "}" 가 여는 중괄호 "{" 후에 바로 나와야 하는 null 문인 경우를 제외하고는, 여는 문장과 동일한 들여쓰기를 하는 새로운 줄에서 사용하자.
ex) class Sample extends Object {
int ivar1;
int ivar2;
Sample(int i, int j) {
ivar1 = i;
ivar2 = j;
}
int emptyMethod() {}
...
}
▷ 메서드들을 구분하기 위해서 각 메서드들 사이에는 한 줄을 비우도록 하자.
ex)
argv++; // 올바른 사용법
argc--; // 올바른 사용법
argv++; argc--; // 이렇게 작성하는 것은 피해라!
▷ 둘러싸여진 문들은 복합문보다 한 단계 더 들여쓰기를 한다.
▷ 여는 중괄호("{")는 복합문을 시작하는 줄의 마지막에 위치해야 한다.
▷ 닫는 중괄호("}")는 새로운 줄에 써야 하고, 복합문의 시작과 같은 들여쓰기를 한다.
▷ 중괄호들이 if-else 문이나 for 문 같은 제어 구조의 일부분으로 사용되어질 때에는 이러한 중괄호들이 모든 문들을 둘러싸는데 사용되어져야 한다.
▷ 이렇게 사용하는 것이 중괄호를 닫는 것을 잊어버리는 것 때문에 발생하는 버그를 만들지 않고, 문을 추가하는 것에 큰 도움을 준다.
return;
return myDisk.size();
return (size ? size : defaultSize);
if (condition) {
statements;
}
if (condition) {
statements;
} else {
statements;
}
if (condition) {
statements;
} else if (condition) {
statements;
} else {
statements;
}
ex)
if (condition) // 이렇게 중괄호 {}를 생략해서 사용하지 말자!
statements;
for (initialization; condition; update) {
statements;
}
ex) for (initialization; condition; update);
while (condition) {
statements;
}
while (condition);
do {
statements;
} while (condition);
switch (condition) {
case ABC:
statements;
/* 다음줄로 계속 진행한다. */
case DEF:
statements;
break;
case XYZ:
statements;
break;
default:
statements;
break;
}
try {
statements;
} catch (ExceptionClass e) {
statements;
}
ex)
try {
statements;
} catch (ExceptionClass e) {
statements;
} finally {
statements;
}
▷ 메서드들 사이에서
▷ 소스 파일의 섹션들 사이에서
▷ 클래스와 인터페이스의 정의 사이에서
▷ 메서드 안에서의 지역 변수와 그 메서드의 첫 번째 문장 사이에서
▷ 블록(Block) 주석 또는 한 줄(Single-Line) 주석 이전에
▷ 가독성을 향상시키기 위한 메서드 내부의 논리적인 섹션들 사이에
ex)
while (true) {
...
}
(메서드 호출과 키워드를 구별하는데 도움을 준다)
ex)
a += c + d;
a = (a + b) / (c * d);
while (d++ = s++) {
n++;
}
printSize("size is " + foo + "\n");
ex) for (expr1; expr2; expr3)
ex)
myMethod((byte) aNum, (Object) x);
myMethod((int) (cp + 5), ((int) (i + 3))
+ 1);
식별자 타입 | 명명 규칙 | 예제 |
Packages | - 패키지 이름의 최상위 레벨은 항상 ASCII 문자에 포함되어 있는 소문자 | com.sun.eng com.apple.quicktime.v2 edu.cmu.cs.bovik.cheese |
Classes | - 클래스 이름은 명사 | class Raster; class ImageSprite; |
Interfaces | - 인터페이스 이름도 클래스 이름과 같은 대문자 사용 규칙을 적용. | interface RasterDelegate; interface Storing; |
Methods | - 메서드의 이름은 동사 - 복합 단어일 경우 첫 단어는 소문자로 시작하며, 그 이후에 나오는 단어의 첫 문자는 대문자로 사용(CamelCase 방식) | run(); runFast(); getBackground(); |
Variables | - 변수 이름의 첫 번째 문자는 소문자로 시작 - 각각의 내부 단어의 첫 번째 문자는 대문자로 시작 - 변수 이름이 언더바(_) 또는 달러 표시 문자로 시작하지 않도록 주의 - 변수 이름은 짧지만 의미 있어야 한다. - 변수 이름의 선택은 그 변수의 사용 의도를 알아낼 수 있도록 의미적 - 한 문자로만 이루어진 변수 이름은 임시적으로만 사용하고 버릴 변수일 경우를 제외하고는 피해야 한다. | Int i; char c; float myWidth; |
Constants | - 클래스 상수로 선언된 변수들과 ANSI 상수들의 이름은 모두 대문자로 | static final int MIN_WIDTH = 4; static final int MAX_WIDTH = 999; static final int GET_THE_CPU = 1; |
(인스턴스 변수들은, 명시적으로 선언될 필요가 없는 경우도 많다)
▷ 만약 class 대신 struct를 사용해야 하는 경우라면, class의 인스턴스 변수들을 public으로 선언하는 것이 적합하다.
ex)
classMethod(); // 좋은 사용법
AClass.classMethod(); // 좋은 사용법
anObject.classMethod(); // 나쁜 사용법
ex) fooBar.fChar = barFoo.lchar = 'c'; // 이렇게 사용하지 말자!
ex)
if (c++ = d++) { // 이렇게 사용하지 말자! (자바가 허용하지 않음)
...
}
ex) 아래처럼 작성할 것
if ((c++ = d++) != 0) {
....
}
ex) d = (a = b + c) + r; // 이렇게 사용하지 말자!
// 아래처럼 쓸 것
a = b + c;
d = a + r;
▷ 연산자 우선순위 문제를 피하기 위해서 복합 연산자를 포함하는 경우에는 자유롭게 괄호를 사용하는 것이 좋은 생각이다.
▷ 나는 연산자 우선 순위를 확실하게 알고 있다고 할지라도, 다른 프로그래머에게는 생소할 수 있다는 것을 기억하자.
ex)
if (a == b && c == d) // 이렇게 사용하지 말자!
if ((a == b) && (c == d)) // 이렇게 사용하자!
▷ 프로그램의 구조와 목적이 일치해야 한다.
ex)
if (booleanExpression) {
return true;
} else {
return false;
}
// 다음과 같은 형식이 더 좋음
return booleanExpression;
ex)
if (condition) {
return x;
}
return y;
// 다음과 같은 형식으로 작성
return (condition ? x : y);
▷ 삼항 연산자(ternary operator - ?:) 에서 ? 이전에 이항 연산자(binary operator)를 포함하는 식(expression)이 있는 경우에는, 꼭 괄호를 사용해야 한다.
ex) (x >= 0) ? x : -x;