6. 선언 (declarations)
6.1. 한 줄 선언
- 한 줄에 하나의 선언을 권장한다.
- 같은 줄에 다른 타입을 두지 말라. (array와 일반 변수)
- 타입과 이름을 공백 하나로 구분할 수도 있지만, 탭을 사용할 수도 있다.
int level; // indentation level
int size; // size of table
Object currentEntry; // currently selected table entry
6.2. 배치 (placement)
선언은 블럭의 시작에 항상 위치시켜라.
void MyMethod() {
int int1; // beginning of method block
if (condition) {
int int2; // beginning of "if" block
...
}
}
- for문 내의 선언은 예외로 한다.
- 상위 수준에 이미 존재하는 이름으로 선언을 하지 말라.
6.3. 초기화
초기화는 변수가 선언되는 시점에서 한다. 계산 결과에 따라 초기값이 바뀌는 경우에는 초기화를 나중으로 미룰 수 있다.
6.4. 클래스와 인터페이스 선언들
- 메소드 이름과 파라미터 리스트 시작괄호 "(" 사이에는 공백이 없어야 한다.
- 시작 중괄호 "{"는 선언문과 같은 줄의 제일 끝에 나타낸다.
- 닫는 중괄호 "}"는 "{"와 같은 수준으로 들여쓰기를 해야 한다. null 문인 경우는 예외로 한다.
class Sample extends Object {
int ivar1;
int ivar2;
Sample(int i, int j) {
ivar1 = i;
ivar2 = j;
}
int emptyMethod() {}
...
}
- 메소드들은 빈 줄에 의해서 분리된다.
7. 문장 (statements)
7.1. 단일문 (simple statements)
각 줄은 최대 하나의 문장을 포함한다. 명백한 이유가 없다면, 콤마로 여러 문장들을 묶어서 사용하지 마라.
7.2. 복합문 (compound statements)
복합문은 중괄호 "{ 문장들 }"로 둘러싸여진 문장 리스트를 포함하는 것을 말한다.
- 둘러싸여진 문장들은 복합 문장보다 한 레벨 더 들여쓰기를 해야 한다.
- 여는 중괄호는 복합문을 시작하는 줄의 끝에 위치한다; 닫는 중괄호는 새로운 줄에 쓰고, 복합 문장의 시작과 같은 레벨에서 들여쓰기를 해야 한다.
- 문장들이 if-else나 for문과 같은 제어구조의 일부분 일 때에, 심지어 문장이 한줄(singleton)일지라도 중괄호를 쓴다. 이렇게 사용하면 중괄호를 닫는 것을 잊어버려서 발생하는 버그 없이 문장을 추가하는 것이 더 쉽게 만든다.
7.3. 리턴문 (return statements)
값을 가지는 return 문은 더 명백한 return값을 가지는 경우를 제외하고는 괄호를 사용하지 않는다.
7.4. if, if-else, if else-if else 문
아래의 형식을 따른다.
if (condition) {
statements;
}
if (condition) {
statements;
} else {
statements;
}
if (condition) {
statements;
} else if (condition) {
statements;
} else if (condition) {
statements;
}
주의 : if문은 항상 중괄호를 명시한다. 아래와 같은 경우는 피하라.
if (condition) //AVOID! THIS OMITS THE BRACES {}!
statement;
7.5. for 문
for 문은 아래와 같은 형식으로 쓴다.
for (initialization; condition; update) {
statements;
}
for (initialization; condition; update); // empty for statement
초기화나 업데이트에서 콤마 연산자를 이용하는 경우에는 최대 3개까지만 변수들을 구분해서 사용해라. 더 필요하면 for문 이전에서 초기화를 하고, loop마지막 부분에서 업데이트를 한다.
7.6. while 문
while 문은 아래처럼 쓴다.
while (condition) {
statements;
}
while (condition); // empty while statement
7.7. do-while 문
do {
statements;
} while (condition);
7.8. switch 문
switch (condition) {
case ABC:
statements;
/* falls through */
case DEF:
statements;
break;
case XYZ:
statements;
break;
default:
statements;
break;
}
- break가 없이 다음 case로 이어서 실행되는 경우에는 /* falls through */ 주석을 덧붙인다.
- 모든 switch 문은 default case를 반드시 포함해야 한다. default에서 break는 없어도 될 것 같지만, 나중에 case가 덧붙을 것을 예상할 수 있다.
7.9. try-catch 문
try {
statements;
} catch (ExceptionClass e) {
statements;
}
8. 공백
8.1. 빈 줄
빈 줄은 논리적으로 관계된 코드들의 영역들을 분리함으로 해서 가독성을 향상시킨다.
아래는 2줄을 비우는 경우이다:
- 소스 파일의 영역들 사이
- 클래스와 인터페이스 정의 사이
아래는 1줄을 비우는 경우이다:
- 메소드들 사이
- 메소드 내의 로컬 변수와 메소드의 첫 문장 사이
- 블럭 주석과 단일(single-line) 주석 이전
- 메소드 내의 논리 영역 사이에서 가독성을 높이기 위한 경우
8.2. 빈 칸
- 키워드 이후에 괄호가 오는 경우
while (true) {
...
}
메소드 이름과 메소드의 여는 괄호 사이에는 빈칸을 넣으면 안 된다. 이렇게 하면 메소드 호출과 키워드를 구별하는데 도움을 준다.
- 인자 리스트에서 콤마 다음에 빈칸을 넣는다.
- .(점)을 제외한 모든 binary 연산자는 피연산자들과 빈 칸으로 구분한다. unary 연산자 "++", "--"를 나누기 위해서 빈 칸을 사용하면 안된다.
a += c + d;
a = (a + b) / (c * d);
while (d++ = s++) {
n++;
}
prints("size is " + foo + "\n");
- for 문에서 표현식(expression)은 빈 칸으로 분리한다.
for (expr1; expr2; expr3)
- 캐스팅(cast)은 빈 칸으로 분리한다.
myMethod((byte) aNum, (Object) x);
myFunc((int) (cp + 5), ((int) (i + 3))
+ 1);
9. 명명법 (naming conventions)
Packages - 유일한 패키지 이름의 앞 부분은 항상 모두 소문자로 쓴다.
Classes - 클래스 이름은 명사. 조합어인 경우 각 단어의 첫 글자는 대문자로 한다. 잘 알려지지 않은 두문자어와 약어는 피하라.
Interfaces - 클래스 이름과 같이 대문자화 한다.
Methods - 메소드의 이름은 동사. 첫 문자는 항상 소문자로 하고, 조합어인 경우 두 번째 단어부터 대문자로 쓴다.
Variables - 변수 이름의 첫 번째는 소문자로 하고 두 번째 단어부터 대문자로 한다. 짧지만 의미가 있도록 이름을 붙인다. 사용의도를 충분히 나타낼 수 있도록 의미가 있어야 한다. 임시 변수를 사용하는 경우, 정수형인 경우 i, j, k, m, n을 사용하고 문자형인 경우 c, d, e를 사용한다.
Constants - 클래스 상수로 선언된 변수들과 ANSI 상수들의 이름은 모두 대문자로 하고, 각 단어는 언더스코어"_"로 분리한다.
10. Programming 습관
10.1. 인스턴스 변수와 클래스 변수에 대한 접근을 제공
어떠한 인스턴스 변수나 클래스 변수라도 합당한 이유없이 public으로 선언하지 않아야 한다. 인스턴스 변수들은 명시적으로 선언될 필요가 없을 경우가 많다. 인스턴스 변수가 public으로 선언되어야 하는 적당한 경우는 클래스가 행위(behavior)를 가지지 않는 자료구조인 경우이다. 다시 말해서 만약 class 대신 struct를 사용해야 한다면(Java가 struct를 지원한다면), class의 인스턴스 변수들을 public으로 선언하는 것이 적합하다.
10.2. 클래스 변수와 메소드의 참조
클래스(static) 변수나 메소드를 접근하기 위해서 객체를 사용하면 안 된다. 대신 클래스 이름을 사용한다.
classMethod(); //OK
AClass.classMethod(); //OK
anObject.classMethod(); //AVOID!
10.3. 상수
숫자 상수는 for 루프에서 카운트 값으로 나타나는 –1, 0, 1을 제외하고는 직접적으로 코딩 되어서는 안 된다.
10.4. 변수 할당
단일문에서 같은 값을 여러 변수에 할당하면 안된다.
fooBar.fChar = barFoo.lchar = 'c'; // AVOID!
일치 연산자(equality operator)와 쉽게 혼동될 수 있는 곳에서 할당하지 말아야 한다.
if (c++ = d++) { // AVOID! Java disallows
...
}
if ((c++ = d++) != 0) { // Ok
...
}
실행시간 성능 향상을 위해서 할당문을 중첩으로 사용하지 말아야 한다. 최적화는 컴파일러의 몫이다.
d = (a = b + c) + r; // AVOID!
a = b + c; // Ok
d = a + r;
10.5. 기타 여러 습관
10.5.1. 괄호
연산자 우선순위 문제를 해결하기 위해서 괄호를 적당히 많이 사용하는 것은 좋은 생각이다.
if (a == b && c == d) // AVOID!
if ((a == b) && (c == d)) // RIGHT
10.5.2. 리턴 값
프로그램의 구조를 목적에 맞도록 만들려고 노력하라.
if (booleanExpression) { // boolean 값에 따라 boolean값을 리턴한다.
return TRUE;
} else {
return FALSE;
}
-----------------------------
return booleanExpression; // 이 한 줄로 가능하다.
if (condition) { // boolean값은 아니지만, if문과 else에서 값 리턴만 수행한다.
return x;
}
return y;
-----------------------------
return (condition ? x : y); // if를 없애고 삼항 연산자를 사용할 수 있다.
10.5.3. 삼항 연산자(a ? b : c)에서 ? 이전의 표현식
? 이전에 오는 표현식은 괄호로 묶어야 한다.
(x >= 0) ? x : -x
10.5.4. 특수한 주석
현재 동작은 하지만 신뢰할 수 없는(bogus) 내용을 표시하기 위해서, 주석내에 XXX를 표기하라. 신뢰할 수도 없고 제대로 동작하지도 않는(broken) 경우에는 FIXME를 표기하라.
11. References
[1] Code Conventions for Java Programming Language (English)
http://java.sun.com/docs/codeconv/
[2] Code Conventions for Java Programming Language (Korean, Translated by 오광신)
http://www.javastudy.co.kr/docs/lec_ProgrammingGuide/okshin/JavaCodeConventions.htm
이올린에 북마크하기