문서의 이전 판입니다!
JAVA를 작성할 때 참고해야 할 것들
JDK : Java Development Kit 자바 프로그램을 개발하기 위한 개발킷으로 컴파일러와 디버거등이 포함되어 있음.
JRE : Java Runtime Environment 자바 프로그램을 실행(Run)하기 위한 환경
JVM : Java Virtual Machine 자바가 어떤 운영체제 환경에서나 실행될 수 있도록 만들어진 가상 머신. 자바의 개발 모토(WORA : Write Once Run Anywhere 어디에서나 쓰고 읽을 수 있는
)를 구현하기 위한 핵심 기술이다.
Compiletime↔Runtime 컴파일타임(CompileTime)은 편집과정(소스코드를 작성하고 컴파일러(컴퓨터가 알아들을 수 있도록 기계어로 번역해주는 것)를 거쳐 실행 가능한 프로그램으로 만드는 것)이며 런타임(RunTime)은 사용자에 의한 실행 → 응용프로그램이 동작되어지는 과정
이 개념을 이해해야 Error 유형과 그 메시지를 이해할 수 있다. 웹프로그래밍에서는 프론트엔드(Front End)와 백엔드(Back End) 또는 클라이언트 사이드(Client Side)와 서버 사이드(Server Side)의 두 가지로 나눌 수 있는데, 여기에서 사용자의 브라우저에서 읽혀지는 소스코드에서의 에러와 웹서버에서 해석되는 소스코드의 에러의 형태로 세분화될 수 있다.
자바에서 쓰이는 기호들
이 작은 겨자씨같은 기호들이 프로그램에서 얼마나 함축적인 의미들을 가지며, 만약 빼놓으면 심각한 오류들을 발생하는지 프로그래밍을 해보면 잘 알게 될 것이다.
( )소괄호(Parenthesis) | { } 중괄호(Brace) | [ ] 대괄호 Bracket |
수식 (Number Sentence) | |||
---|---|---|---|
+ Addition | - Subtraction | * Multiplication | / division |
더하기는 그냥 plus 빼기는 minus 곱하기는 times, multiplied by 나누기는 divided by 라고 한다.
= Equal | < Less than sign | > Greater than sign |
결합형 | ||
---|---|---|
⇐ Less or Equal | >= Greater than or Equal | == Double Equal |
※ 에러를 발생시키지는 않지만 약속된 규칙들
식별자(identifiers)-Class/InterFace/Method/Variable-의 이름을 지을 때 따라야 할 규칙. 모양이 낙타를 닮았다고 해서 Camel Case라고 부른다.
ex) luckySeven, myHouse, firstName 등
ex) 777lucky (X) , lucky777 (O)
ex) addFast, addfast는 각기 다른 변수로 취급
name | Convention | Examples |
---|---|---|
Project | 대문자 사용을 권장 | HOMEPAGE |
Class | 대문자로 시작하고, 명사를 사용 | class Thread/ class Raster/ class ImageSprite/ |
Interface | 대문자로 시작하고, 형용사를 사용 | interface Runnable/ interface RasterDelegate/ interface Storing/ |
method | 소문자로 시작하고, 동사를 사용 | add()/ runFast()/ getBackground() |
variable 변수 | 소문자로 시작 | int i/ char c; float myWidth; String phoneNumber |
package | 소문자로 시작 | com.sun.eng / edu.cmu.cs.bovik.cheese |
constant 상수 | 대문자로 시작 | static final int MAX_WIDTH = 999; static final int GET_THE_CPU = 1; |
언더 하이픈( _ ) 으로 단어를 구분하는 표기법 (마치 뱀처럼 생겨서 Snake_Case)
(상수와 DB 컬럼명은 보통 스네이크케이스 명명규칙을 따름)
ex) background_color 등
원문 : Oracle / Code Conventions for JavaTM Programming Language / 1999-4-20
번역 : Kwangshin's Positive Blog, Java Code Conventions / 자바 코딩 규칙, 2015-2-10
왜 코딩 규칙(Code Convention)이 필요한가?
코딩 규칙은 여러 가지 이유에서 프로그래머에게 중요하다 ↓
이 장에서는 흔하게 사용되는 파일 확장자와 파일 이름을 설명한다.
자바 소프트웨어는 다음의 파일 확장자를 사용한다.
파일 형태 | 확장자 |
---|---|
자바소스 | .java |
자바 바이트코드 | .class |
파일 이름 | 사용 |
---|---|
GNUmakefile | make 파일 이름으로 사용, 소프트웨어를 빌드할 때는 gnumake 명령어를 사용 |
README | 특정 디렉토리의 내용을 요약하는 파일 이름으로 사용 |
파일은 빈 줄이나 다른 구역임을 나타내주는 주석으로 나누어지는 여러 구역(section)들로 구성되어 있다.
2,000 라인을 넘는 파일은 이해하기가 쉽지 않기 때문에 될 수 있으면 피해야 한다.
적절하게 구성된 자바 프로그램의 예제는 아래 3.11.1 자바 소스파일 예제에서 볼 수 있다.
각각의 자바 소스 파일은 하나의 public 클래스 또는 인터페이스를 가진다. private 클래스들과 인터페이스들이 public 클래스와 연결되어 있을 때, public 클래스와 같은 파일에 private 클래스들과 인터페이스들을 넣을 수 있다. public 클래스는 파일에서 첫 번째 클래스 또는 인터페이스이어야 한다.
자바 소스 파일은 다음과 같은 순서를 가진다.
모든 소스 파일은 클래스 이름, 버전 정보, 날짜, 저작권 주의를 보여주는 C 스타일의 주석과 함께 시작한다.
1 2 3 4 5 6 7 8 9 |
/* * 클래스 이름 * * 버전 정보 * * 날짜 * * 저작권 주의 */ |
대부분의 자바 소스 파일에서 주석이 아닌 첫 번째 줄은 Package 문이다. 그 후에 Import 문이 뒤따라 나온다. 예를들면 다음과 같다 ↓
1 2 3 |
package java.awt; import java.awt.peer.CanvasPeer; |
다음 표는 클래스(Class) 또는 인터페이스(Interface) 선언의 일부분들을 나타나는 순서에 따라 보여준다.
순서 | 클래스/인터페이스 선언의 구성요소 | 설명 |
---|---|---|
1 | 문서화 주석 | (/*… */) 이 주석이 포함하는 정보들은 아래 “5장의 2절 문서화(Documentation) 주석”을 참고 |
2 | 클래스/인터페이스 문 | |
3 | 구현 주석 | (/* … */) 이 주석은 클래스/인터페이스 문서화 주석에 적합하지 않은 하나의 클래스/인터페이스에만 해당하는 정보들을 포함해야 한다. |
4 | 클래스(static) 변수 | 첫번째로는 public 클래스 변수들이 나오고, 그 다음에 protected 클래스 변수들, 그 다음에 package(접근 제한자가 없는 경우) 클래스 변수들, 그 다음에 private 클래스 변수들이 나온다. |
5 | 일반 변수 | 작성하는 순서는 클래스 변수와 동일하다. |
6 | 생성자 | |
7 | 메서드 | 메서드들은 범위나 접근성을 기준으로 나누기 보다는 기능성에 의해서 구성되어야 한다. 예를 들어, private 클래스 메서드가 두 개의 public 메서드들 사이에 존재할 수도 있다. 이렇게 하는 목적은 코드가 더 쉽게 읽히고, 더 쉽게 이해되도록 돕기 위해서이다. |
4개의 빈 칸(space)를 들여쓰기 단위로 사용한다. 들여쓰기의 정확한 구현(빈 칸을 사용하거나 탭을 사용하거나)은 정해져 있지 않다. 탭은 4개의 빈 칸이 아니라, 8개의 빈 칸으로 설정하는 것이 좋다.
한 줄에 80자 이상 쓰는 것은 대부분의 터미널(terminal)과 툴에서 다룰 수 없기 때문에 피해야 한다.
* 문서화 주석을 가지고 문서를 만들 때, 일반적으로 한 줄에 70자 이상을 가지지 않는다.
하나의 식이 한 줄에 들어가지 않을 때에는, 다음과 같은 일반적인 원칙들을 따라서 두 줄로 나눈다.
만약 위의 원칙들이 코드를 더 복잡하게 하거나 오른쪽 끝을 넘어간다면, 대신에 8개의 빈 칸을 사용해 들여쓴다.
여기 메서드 호출을 두 줄로 나누어 쓰는 몇 가지 예제들이 있다.
1 2 3 4 5 6 |
someMethod(longExpression1, longExpression2, longExpression3, longExpression4, longExpression5); var = someMethod1(longExpression1, someMethod2(longExpression2, longExpression3)); |
다음은 수학 표현식을 두 줄로 나누어 작성하는 두 개의 예제이다. 첫번째 예제가 괄호로 싸여진 표현식 밖에서 줄 바꿈이 일어나고 더 높은 레벨이기 때문에 첫번째 예제를 더 많이 사용한다.
1 2 3 4 5 |
longName1 = longName2 * (longName3 + longName4 - longName5) + 4 * longname6; // 될 수 있으면 이 방법을 사용한다. longName1 = longName2 * (longName3 + longName4 - longName5) + 4 * longname6; // 될 수 있으면 피한다. |
다음은 메서드 선언을 들여쓰는 예제들이다. 첫번째는 일반적인 경우이다. 두번째 예제의 경우 일반적인 들여쓰기를 사용한다면 두번째 줄과 세번째 줄을 들여써야 하므로, 대신에 8개의 빈 칸을 이용하여 들여쓴다.
1 2 3 4 5 6 7 8 9 10 11 12 |
// 일반적인 들여쓰기 someMethod( int anArg, Object anotherArg, String yetAnotherArg, Object andStillAnother) { ... } // 너무 멀리 들여쓰는 것을 피하기 위해 8개의 빈 칸으로 들여쓰기 private static synchronized horkingLongMethodName( int anArg, Object anotherArg, String yetAnotherArg, Object andStillAnother) { ... } |
일반적으로 메서드 본문이 시작할 때 4개의 빈 칸을 사용하므로, 메서드 본문과 구분하기 위해서 줄을 나누는 경우의 들여쓰기는 일반적으로 8개의 빈 칸 원칙을 사용하자 예를 들면 다음과 같다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// 아래와 같은 들여쓰기는 사용하지 말자. if ((condition1 && condition2) || (condition3 && condition4) ||!(condition5 && condition6)) { // 좋지 않은 들여쓰기 doSomethingAboutIt(); // 메서드 본문 시작이 명확하지가 않다. } // 대신에 아래와 같은 들여쓰기를 사용한다. if ((condition1 && condition2) || (condition3 && condition4) ||!(condition5 && condition6)) { doSomethingAboutIt(); } // 또는 아래와 같은 들여쓰기를 사용한다. if ((condition1 && condition2) || (condition3 && condition4) ||!(condition5 && condition6)) { doSomethingAboutIt(); } |
다음은 삼항식(ternary expression)에서 사용 가능한 세 가지 방법이다.
1 2 3 4 5 6 7 8 |
alpha = (aLongBooleanExpression) ? beta : gamma; alpha = (aLongBooleanExpression) ? beta : gamma; alpha = (aLongBooleanExpression) ? beta : gamma; |
자바 프로그램은 두 가지 종류의 주석을 가진다.
1 2 3 4 |
/** * Example 클래스는 ... */ public class Example { ... |
1 2 |
int level; // 들여쓰기 단위 int size; // 테이클 크기 |
1 |
int level, size; |
1 |
int foo, fooarray[]; //절대 이렇게 사용하지 말자 |
1 2 3 |
int level; // 들여쓰기 단위 int size; // 테이블 크기 Object currentEntry; // 테이블에서 현재 선택된 데이터 |
1 2 3 4 5 6 7 8 |
void myMethod() { int int1 = 0 ; // 메서드 블록의 시작 if (condition) { int int2 = 0 ; // "if" 블록의 시작 ... } } |
1 |
for ( int i = 0 ; i < maxLoops; i++) { ... } |
1 2 3 4 5 6 7 8 9 |
int count; ... myMethod() { if (condition) { int count = 0 ; // 이렇게 사용하지 말 것! ... } ... } |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class Sample extends Object { int ivar1; int ivar2; Sample( int i, int j) { ivar1 = i; ivar2 = j; } int emptyMethod() {} ... } |
1 2 3 |
argv++; // 올바른 사용법 argc--; // 올바른 사용법 argv++; argc--; // 이렇게 작성하는 것은 피해라 |
1 2 3 4 5 |
return ; return myDisk.size(); return (size ? size : defaultSize); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
if (condition) { statements; } if (condition) { statements; } else { statements; } if (condition) { statements; } else if (condition) { statements; } else { statements; } |
1 2 3 |
for (initialization; condition; update) { statements; } |
1 |
for (initialization; condition; update); |
1 2 3 |
while (condition) { statements; } |
1 |
while (condition); |
1 2 3 |
do { statements; } while (condition); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
switch (condition) { case ABC: statements; /* 다음줄로 계속 진행한다. */ case DEF: statements; break ; case XYZ: statements; break ; default : statements; break ; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
try { statements; } catch (ExceptionClass e) { statements; } try - catch 문은 try 블록이 성공적으로 완료되든지, 아니면 중간에 에러가 발생하든지에 상관없이 실행되어야 하는 부분을 추가하기 위해서 finally 부분을 사용할 수 있다. try { statements; } catch (ExceptionClass e) { statements; } finally { statements; } |
1 2 3 |
while ( true ) { ... } |
1 2 3 4 5 6 |
a += c + d; a = (a + b) / (c * d); while (d++ = s++) { n++; } |
1 |
printSize( "size is " + foo + "\n" ); |
1 2 |
myMethod(( byte ) aNum, (Object) x); myMethod(( int ) (cp + 5 ), (( int ) (i + 3 )) + 1 ) |
명명 규칙, 즉 이름을 정하는 규칙은 프로그램을 더 읽기 쉽게 만들어 줌으로써 더 이해하기 쉽게 만들어 준다. 또한 식별자(identifier)를 통해서 기능에 대한 정보도 얻을 수 있다. 예를 들자면, 그것이 상수인지 패키지인지 클래스인지를 알 수 있도록 도와준다. 이러한 정보는 코드를 이해하는데 큰 도움이 된다.
본 장에서 소개할 명명 규칙의 식별자 타입은 다음 6가지이다.
명명 규칙은 다음과 같다.
예를 들면 부서명, 팀명, 프로젝트명, 컴퓨터 이름, 또는 로그인 이름 등이다.
예제는 다음과 같다.
1 2 3 |
com.sun.eng com.apple.quicktime.v2 edu.cmu.cs.bovik.cheese |
명명 규칙은 다음과 같다.
예제는 다음과 같다.
1 2 |
interface RasterDelegate; interface Storing; |
명명 규칙은 다음과 같다.
예제는 다음과 같다.
1 2 3 |
run(); runFast(); getBackground(); |
명명 규칙은 다음과 같다.
예제는 다음과 같다.
1 2 3 |
int i; char c; float myWidth; |
명명 규칙은 다음과 같다.
이름은 짧지만 의미 있어야 한다.
예제는 다음과 같다.
1 2 3 |
int i; char c; float myWidth; |
명명 규칙은 다음과 같다.
예제는 다음과 같다.
1 2 3 |
static final int MIN_WIDTH = 4 ; static final int MAX_WIDTH = 999 ; static final int GET_THE_CPU = 1 ; |
인스턴스 변수 또는 클래스 변수를 합당한 이유없이 public으로 선언하지 말자. 인스턴스 변수들은 명시적으로 선언될 필요가 없는 경우가 많다.
인스턴스 변수가 public으로 선언되는 것이 적절한 경우는 클래스 자체가 어떤 동작(behavior)을 가지지 않는 데이터 구조일(data structure) 경우이다. 다시 말해서 만약 class 대신 struct를 사용해야 하는 경우라면(만약 Java가 struct를 지원한다면) class의 인스턴스 변수들을 public으로 선언하는 것이 적합하다.
클래스(static) 변수 또는 클래스 메서드를 호출하기 위해서 객체를 사용하는 것을 피해야 한다. 대신에 클래스 이름을 사용해라
1 2 3 |
classMethod(); // 좋은 사용법 AClass.classMethod(); // 좋은 사용법 anObject.classMethod(); // 나쁜 사용법 |
숫자 상수는 카운트 값으로 for 루프에 나타나는 -1, 0, 1을 제외하고는 숫자 자체를 코드에 사용하지 않는다.
하나의 문(statement)에서 같은 값을 여러 개의 변수들에 할당하지 말자(이렇게 하면 읽기가 어렵게 된다)
1 |
fooBar.fChar = barFoo.lchar = 'c' ; // 이렇게 사용하지 말자 |
비교 연산자(equality operator: ==)와 혼동되기 쉬운 곳에 할당 연산자(assignment operator: =)를 사용하지 말자
1 2 3 4 5 6 7 8 9 |
// 이렇게 사용하지 말자 (자바가 허용하지 않음) if (c++ = d++) { ... } // 다음과 같이 써야 한다 if ((c++ = d++) != 0 ) { ... } |
실행시 성능 향상을 위해서 할당문(assignment statement)안에 또 다른 할당문을 사용하지 말자
1 2 3 4 5 6 |
// 이렇게 사용하지 말자 d = (a = b + c) + r; // 다음과 같이 써야 한다 a = b + c; d = a + r; |
연산자 우선순위 문제를 피하기 위해서 복합 연산자를 포함하는 경우에는 자유롭게 괄호를 사용하는 것이 좋은 생각이다(작성자는 연산자 우선 순위를 확실하게 알고 있다고 할지라도, 다른 프로그래머에게는 생소할 수 있다는 것을 기억하자).
1 2 |
if (a == b && c == d) // 이렇게 사용하지 말자 if ((a == b) && (c == d)) // 이렇게 사용하자 |
프로그램의 구조와 목적이 일치해야 한다.
1 2 3 4 5 6 |
// 이렇게 사용하지 말자 if (booleanExpression) { return true ; } else { return false ; } |
1 2 3 4 5 6 7 |
// 다음과 같이 써야 한다 return booleanExpression; // 이렇게 사용하지 말자 if (condition) { return x; } return y; |
1 2 |
// 다음과 같이 써야 한다 return (condition ? x : y); |
삼항 연산자(ternary operator - ?:) 에서 ? 이전에 이항 연산자(binary operator)를 포함하는 식(expression)이 있는 경우에는, 꼭 괄호를 사용해야 한다.
1 |
(x >= 0) ? x : -x; |