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

Posted by nucl23

이 글의 원글은 http://java.sun.com/docs/codeconv/ 에 있는 "Code Conventions for Java Programming Language"이며, 조호진(Hojin Cho)에 의해서 번역되었습니다. 혼자 공부하는 차원에서 요약하려다, 요약할 내용이 없어 그냥 번역하게 되었습니다.


1. 소개

1.1. Code conventions가 필요한 이유

 - 처음 개발자가 끝까지 유지보수 하는 경우가 거의 없다.
 - 소프트웨어의 가독성(readability)를 높이고, 새로운 코드를 더 빨리 그리고 전체적으로 이해할 수 있도록 한다.



2. 파일 이름

2.1. 파일 확장자

자바 소스 - .java
자바 바이트코드 - .class



3. 파일 구조

하나의 파일은 각각의 구역(section)을 분리하는 빈 줄들(blank lines)과 각 구역을 식별(identify)하기 위한 주석으로 구성된다.
2000 라인 이상이 되는 파일들은 다루기 힘들며, 이런 경우는 피해야 한다.

3.1. 자바 소스

각 자바 소스 파일들은 하나의 public 클래스 또는 인터페이스를 포함한다. 여러 private 클래스들과 인터페이스들이 public 클래스와 관련되는 경우에는, 그 private 개체들을 public class와 같은 파일에 넣을 수 있다. public 클래스는 파일 내에서 첫 번째 클래스(혹은 인터페이스)여야 한다.

자바 소스 파일의 순서
 - 시작 주석
 - package 와 import 문들(statements)
 - 클래스와 인터페이스 선언

3.1.1. 시작 주석

모든 소스 파일들은 프로그래머, 날짜, 저작권 알림, 프로그램의 목적에 대한 간단한 설명을 포함하는 c-style의 주석으로 시작해야 한다. 아래는 그 예제이다.

/*
 * Classname
 *
 * Version info
 *
 * Copyright notice
 */


3.1.2. package 와 import 문


대부분 자바 소스파일들에서 처음으로 등장하는 주석이 아닌 내용은 package 문이다. 그 이후에 import문이 온다.


3.1.3. 클래스와 인터페이스 정의들

왼쪽의 번호(1~6)은 나타나는 순서를 의미한다. 아래 테이블의 1번부터 6번까지 순서대로 나타나야 한다.

사용자 삽입 이미지



4. 들여쓰기 (Indentation)

들여쓰기는 공백 4칸 으로 한다. 탭은 정확히 공백 8칸 이어야 한다.


4.1. 한 줄 길이

한 줄에 80자 이상의 문자가 들어가면 많은 터미널과 툴에서 다룰 수 없기 때문에 이는 피해야 한다.


4.2. 줄 나누기

한 줄에 표현식(expression)이 다 표현되지 않은 경우에, 아래 원칙에 따라 다음 줄로 분리한다.

 - 콤마 후에 분리.
 - 연산자 이전에 분리.
 - 낮은 수준보다는 높은 수준에서 분리. (표현식에서 괄호 하나가 들어갈 때마다 레벨이 낮아진다)
 - 이전 줄에서 같은 수준에 있는 표현식 시작되는 부분으로 새로운 줄을 위치시킨다.
 - 만약 위의 규칙들이 코드를 복잡하게 하거나, 오른쪽 여백에 대해서 코드가 깨어진다면(squished up), 그냥 8칸 들여쓰기를 한다.

메소드 호출 분리 예제:

function(longExpression1, longExpression2, longExpression3,
            longExpression4, longExpression5);

var = function1(longExpression1,
                     function2(longExpression2,
                                   longExpression3));

표현식 분리 예제:

longName1 = longName2 * (longName3 + longName4 - longName5)
                  + 4 * longname6; // PREFER
longName1 = longName2 * (longName3 + longName4
                                      - longName5) + 4 * longname6; // AVOID

메소드 선언 예제: (메소드의 signature가 길어질 경우에는 그냥 8칸 들여쓰기를 한다)

//CONVENTIONAL INDENTATION
someMethod(int anArg, Object anotherArg, String yetAnotherArg,
                   Object andStillAnother) {
...
}

//INDENT 8 SPACES TO AVOID VERY DEEP INDENTS
private static synchronized horkingLongMethodName(int anArg,
          Object anotherArg, String yetAnotherArg,
          Object andStillAnother) {
...
}

문장(statement) 들여쓰기: (보통의 메소드 들여쓰기(4칸)와 구분하기 위해서 8칸 들여쓰기 사용)

//DON’T USE THIS INDENTATION
if ((condition1 && condition2)
    || (condition3 && condition4)
    ||!(condition5 && condition6)) { //BAD WRAPS
doSomethingAboutIt(); //MAKE THIS LINE EASY TO MISS
}

//USE THIS INDENTATION INSTEAD
if ((condition1 && condition2)
        || (condition3 && condition4)
        ||!(condition5 && condition6)) {
    doSomethingAboutIt();
}

//OR USE THIS
if ((condition1 && condition2) || (condition3 && condition4)
        ||!(condition5 && condition6)) {
    doSomethingAboutIt();
}

3항 표현식: (tenary expression)

alpha = (aLongBooleanExpression) ? beta : gamma; 
 
alpha = (aLongBooleanExpression) ? beta
                                                   : gamma; 
 
alpha = (aLongBooleanExpression)
            ? beta
            : gamma;



5. 주석

자바 프로그램은 두 종류의 주석을 가질 수 있다.
 - 구현 주석 : c++에서의 주석과 같으며, /* ... */ 과 // ...  로 사용한다.
 - 문서 주석 : 자바에서만 사용되며 /** ... */ 로 사용한다.

주석을 너무 자주 쓰면 코드의 질을 떨어뜨리기도 한다. 주석의 필요성을 느낄 때는 코드를 더 확실히 재 작성하는 것을 생각해 보아야 한다. (주석이 필요하다는 것은 그만큼 코드를 이해하기 어렵다는 이유이기 때문에)
주석은 별표 또는 다른 문자를 이용하여 큰 박스들 속에 포함되면 안된다.
주석은 문단분리(form-feed)와 백스페이스 등의 문자를 포함하면 안된다.


5.1. 주석 구현 형식

프로그램은 4가지 스타일의 구현 주석을 가질 수 있다.
 - block
 - single-line
 - trailing
 - end-of-line

5.1.1. block 주석

Block 주석은 파일, 메서드, 자료 구조, 알고리즘들의 설명을 제공할 때 사용된다. Block 주석은 각각의 파일이 시작될 때와 메서드 전에 사용된다. 또한 메서드 안에서와 같이 다른 장소에서 사용되어질 수도 있다. 메서드 안에 존재하는 Block 주석은 그것들이 설명하는 코드와 같은 레벨로 들여쓰기를 해야 한다.

Block 주석은 코드의 나머지로부터 분리하기 위해서 처음 한 줄을 비워야 한다.

/*
 * Here is a block comment.
 */

Block 주석의 형식을 고치는 일이 일어나지 않는 특별한 block 주석은 /*- 시작할 수 있다. 예를 들어 :

/*-
 * 여기에는 들여쓰기를 무시하고 싶은 특별한 형태의 주석을 적는다.
 * Here is a block comment with some very special
 * formatting that I want indent(1) to ignore.
 *
 *    one
 *            two
 *                   three
 */


5.1.2. single-line 주석


짧은 주석은 뒤따라 오는 코드와 같은 수준의 들여쓰기를 하여 나타낼 수 있다. 한 줄에 써지지 않으면 block 주석을 사용한다. single-line 주석 앞에는 빈 줄(blank line)이 있어야만 한다.

if (condition) {
    /* Handle the condition. */
    ...
}


5.1.3. trailing 주석

single-line보다 더 짧은 경우의 주석은 코드와 같은 줄에 나타낸다. 주의할 점은 코드와 구분될 수 있도록 충분히 멀리 위치시켜야 한다.

if (a == 2) {
    return TRUE;                /* special case */
} else {
    return isprime(a);         /* works only for odd a */
}

5.1.4. end-of-line 주석

// 주석은 // 이후부터 줄바꿈이 일어나기 전까지의 내용을 주석으로 처리한다. 이 주석은 텍스트 주석을 위해서 여러줄에 걸쳐서 사용하면 안되지만, 코드의 영역들(sections)을 주석 처리(comment out)하기 위하여 여러 줄에 연속되어 사용되어질 수 있다.

if (foo > 1) {
    // Do a double-flip.
    ...
}
else
    return false;             // Explain why here.

//if (bar > 1) {
//
//     // Do a triple-flip.
//     ...
//}
//else
//     return false;

5.2. 문서 주석

문서(문서 작성을 위한 주석)은 자바 클래스, 인터페이스, 생성자, 메소드와 필드들을 설명한다. 나중에 javadoc 등을 이용하여 코드 문서(code documentation)를 자동으로 생성하기 위해서 작성하는 주석이다. /** ... */ 의 형식을 가진다.

/**
 * The Example class provides ...
 */
class Example { ...
Posted by nucl23

BLOG main image
Software Engineering, Reverse Engineering, Programming, Hobbies, etc. by nucl23

카테고리

분류 전체보기 (106)
Profile (1)
Diary (43)
Software Engineering (16)
Design Patterns (3)
Programming (7)
Compiler (4)
Eclipse (1)
Seminar (5)
Misc. (3)
Total : 16,953
Today : 3 Yesterday : 11