2011년 4월 20일 수요일

자바의 메인메소드(Main Method)

자바 프로그램은 클래스와 메소드의 집합체라고 해도 과언이 아니다.
일단 클래스와 메소드를 자바코드로 쓰는 방법을 살펴보자.

class Robot
{
??????????; //이 공간에다가
?????????; //변수를 선언하고 초기화한다.
????????; //이 공간을 필드(fields)라고 부른다.

void method( ) //메소드를 만드는 형식이다.
{
???????; // 역시 클래스처럼
???????; // 중괄호라고 하나? 그거 오픈하고
???????; // 이렇게 몇줄이든 내용을 쓰고
???????; // 아래처럼괄호를 닫으면 된다
???????; // 달려라 달려 로보트야~
} //method 메소드 끝내기

} //Robot 클래스 괄호닫기

클래스와 메소드는 내용의 시작과 끝을 중괄호 기호인 {와 }를 통해 알수 있으며 자바 프로그램은 소스를 읽어들일때 빈칸이나 빈줄은 무시하고 명령어들을 읽어드린다. // 슬래시를 치고 쓰는 내용은 자바에서 읽어드리지 않는다. 여기다 쓰는 내용을 주석이라고 하는데 프로그램에 대한 설명이나 중요한 사항을 메모하는 용도로 사용한다. 프로그램이 길어질때 어떤 클래스나 메소드 괄호인지 찾기 힘들때가 있는데 그럴때 이런식으로 표기해두면 편하다. 그리고 클래스와 메소드 사이에 빈칸이나 빈줄은 자기 마음대로 쓸수 있으나 프로그램의 내용과 구문을 금방 파악하기 위해 괄호의 열고 닫는 위치를 같게 만들고 클래스나 메소드 구문에 관련된 라인을 처음 입력할 때에는 한줄씩 띄우는게 보기 편하다. 지금 위의 코드에서 method라는건 명령어가 아니라 한번 생각해 보라고 메소드 이름 자체를 method라고 써놓은 것이다. 즉 아무 이름이나 쓰고 싶은데로 쓸수 있다. 평소에 자바에서 메소드라는 표현을 쓸때는 "결과값 ???(입력값)" 이 라인 전체를 의미하는 것이다. 이제 명령어 자체가 method라고 착각하는 이는 이 시간 이후로 없길 바란다.

그럼 void는 무엇인가? 자, 사전을 찾아봤다고 가정하고 "void 빈공간,텅빈" 뭐 이런 뜻이 있는데 여기서도 마찬가지로 생각하면 된다. 저번에 필자가 메소드의 형식은 어떻게 쓰는지 말했는데 기억하는가? 모르면 앞에꺼 찾아보자. 결과값이라고 했는데 이제 생각나는가? 안난다면 자기 머리에 꿀밤 한대씩 주고 다시 시작하자. 그렇다. 결과값이다. 그럼 뜻이 비어있으니 뭐겠는가? 결과값을 받지 않겠다는 소리다. 지금 여기서 쓰인 void는 결과값이 없는 메소드다. 무슨 행동을 시켜놓고 결과가 필요없다? 여기서 결과값이란 메소드로 실행하고 나서 다시 그 값이 글자(String)든 정수(int)든 값을 받아서 뭔가 다시 할 필요가 없다는 뜻이다. 그럼 메소드 이름 옆에 괄호안은 뭐였었나? 기억나나? 아까 볼때 못봤나? 머리 안돌아가면 몸이라도 부지런해야한다. 빨리 다시 찾아보자. 그렇다. 입력값이다. 그런데 괄호안이 비었다. 아무것도 없으니 입력값도 없다는 소리다. 즉, 아무 입력값을 받지 않더라도 메소드를 부르면 자동적으로 뭔가를 하라고 지시하는 것이다. 반대로 입력값이 있으면 메소드를 행하기 전에 입력값이 올바른지 점검해보고 계속 진행할지 안할지를 결정할수 있는 메소드를 만들수도 있고 입력값으로 덧셈이나 뺄셈같은 계산을 할수도 있고 암튼 입력값이 있으면 쓰이는 용도가 더 다양해진다고 볼수 있겠다.

public class Test1
{
public static void main(String[ ] args)
{
System.out.println("");
System.out.print("나는 클래스 Te");
System.out.print("st1의 메인 ");
System.out.println("메소드야.");
System.out.println(" ");
System.out.print("모든걸 총괄하는");
System.out.println(" 곳이지.");
System.out.println( );
System.out.println("모두들~ 방가 방가^^ ");
}
}

자 어떤가? 이제 프로그램이 눈에 들어오기 시작하남? 지금 이 예제는 Test1이라는 이름의 클래스 한개와 main이라는 이름의 메소드 한개를 가지고 있는 자바 프로그램이다. 메소드 안에 내용을 보면 뭔지는 모르겠지만 print 어쩌구 저쩌구 하는거 보니 뭔가를 쓰라고 하는 명령어라고 짐작할수 있을 것이다. 더군다나 출력하는 문장을 한글로 써놨는데 이거 감 안오면 정말 난감하다.^^ print라는 뜻은 다 알테니 말그대로 그뜻이고 그렇다면 println은 뭔지 궁금할 것이다. println은 문장을 찍고 엔터를 친 상태 즉 출력후 다음줄에 가서 다음 명령을 대기하라는 소리다. 그럴듯(?)하게 쓸려니 힘들구나. ㅎㅎ 이제 따옴표가 괄호안에 있는게 보일텐데 글자를 출력하려고 할때는 저렇게 괄호 양옆에 따옴표를 쓰고 그 사이에다가 원하는 글자를 입력해야 출력이 된다. 그리고 글자 출력하라는 명령어 끝을 보면 뭔가가 있다. 뭐? 세미콜론(;), 필자가 말하기 전에 신경쓰고 있는 이가 있었을지 모르겠다. 모든 명령의 끝에는 저렇게 ;을 붙여야한다. 그래야 자바 프로그램이 한 라인의 명령어가 끝났구나라면서 알아먹는다. 아까 맨처음 위에서도 세미콜론이 물음표 옆에 있었는데 혹시 누군가가 세미콜론을 왜 썼지라면서 의아해 했다면 그대가 자바 천재(?)임을 필자가 인정하겠다.^^


저번 시간에 이어서 설명할 부분은 바로 메인 메소드다.
public static void main(String[ ] args)
{
명령1;
명령2;
명령3;
.... ;
}

메인메소드의 정의는 프로그램을 실행했을때 자바에서 가장 먼저 읽어들여서 명령들을 다 작동하고 그것이 끝나면 프로그램을 종료하는 공간이 바로 메인메소드이다. 그런 까닭에 결과값은 항상 없다. 프로그램이 끝나는데 결과값을 받아서 또 써먹을때가 없다. 프로그램을 끝내야 하니까 메인메소드는 항상 void이다. 더불어 메인메소드의 이름도 말 그대로 항상 main으로 이름지어야 한다. 왜? 메인메소드이니까...(이렇게 설명하면 몰매 맞겠군.^^*) 그건 자바에서 처음 시작하는 메인메소드의 이름은 반드시 main으로 하라고 자바소스를 읽고 작동시키는 머신 일명, JVM이라고 불리우는 자바가상머신에게 그렇게 입력(?)해 놓았다. 그래서 선택의 여지가 없다. 프로그램을 작동시키려면 main이라는 이름의 메인메소드를 쓸수밖에 없는 것이다.

그럼 안에 입력값이라고 쓰여있는 String[ ] args 는 무엇인가? 일단 String(스트링)은 여러가지 뜻이 있는데 여기선 악기의 "줄"이라는 그런 뜻이 아니고 컴퓨팅에서는 "문자열"이라는 뜻으로 쓰인다. 어쩌다가 이 세계에서 그런 뜻으로 쓰였는지 아는 이 있으면 알려주기 바란다.^^ 그렇다면 [ ] 는 무엇인가? 문자열이 여러개 있다는 뜻인데 이것을 우리는 배열(Array)이라고 한다. 그럼 일단 문자열은 무엇인가? 문자를 한개부터 일렬로 세운거다. 예를 들어, 문자 하나는 "비", 문자 두개는 "Ya", 문자 세개는 "그만혀" 그렇다면 문자열 배열은? {비, Ya, 그만혀} 뭐 이런식으로 모아놓은 것이지 않을까? ㅎㅎㅎ 이런 문자열을 지칭할때 String[ ] 을 쓰고 그 문자열을 지칭하는 이름이 args인 것이다. 솔직히 이름이므로 args 이거는 아무거나 써도 되나 인수 혹은 매개변수라는 뜻의 arguments 약자로 쓰인 것이니 특별한 일이 없는한 바꿀 필요는 없다 하겠다. 한국말이 어렵다. 매개변수는 뭐냐? 이렇게 직설적으로 물으면 대부분 대답하기가 힘들 것이다. 그냥 막연히 무슨 값을 얘기할때 그렇게 쓴다 정도로 이해할텐데 자세히 풀자면 프로그래밍에서 함수(메소드)나 프로시저(메소드 비슷한거..영어다..사전 찾아보자)를 호출할 때 호출하는 쪽에서 실제로 넘겨주는 값을 얘기할때 매개변수라 한다. 뭔가 하나를 알려고 하면 이렇게 끝이 없는 것이다. 음 철학적이군..-

문자열 배열이 왜 필요할까? 지금 위에서 본 문자열 배열중에 세번째 스트링인 "그만혀"만 어디다가 가져와서 쓰고 싶다. 그러면 args[2] 이런식으로 명령해서 불러쓴다. 첫번째 스트링이 필요하면 args[0] 이런식으로 표기해서 불러쓰기 쉽도록 만들어 놓은 것이다. 그리고 방금 눈치빠른 이들만 알아챘겠지만 시작은 0에서 시작한다. 숫자는 0(?)부터 시작하니까 하하~ 왜 1에서 시작하지 0에서 시작했을까? 바로 이것 때문이다. 이 배열에 문자열이 몇개나 있나 물어보면 답이 뭘까? (정말 몰라?) 세개잖어~ 그럼 어떻게 세야되나? 하나 둘 셋...1 2 3...길이를 셀때는 1부터 시작해야 한다. 이해되지? 안되면 큰일이다. 그런데 이렇게 배열을 세어서 알려주는 표기방법이 있다. "이름.length" 여기선 이름이 args 이니까 args.length 로 길이를 물어보는 명령을 넣으면 3이라는 답을 얻을수도 있다. 배열에서는 처음과 끝을 어떻게 알수 있을까는 방금 말한 길이를 통해서 알수 있는데 여기처럼 배열에서 길이를 알면 문자열 세개까지만 검색하고 더이상 시간을 지체할 필요가 없다. 아니면 없는데도 계속 검색하는 바보짓(?)을 하는 경우가 생길테니까 말이다. (물론 자바에서는 없는데 검색하면 null에 관계된 에러가 날것이다. 역쉬~ 자바!)

그럼 메인메소드 안에 배열은 왜 쓴거야? 이렇게 의문을 품은 이들은 아 착하다. 뭐 좀 먹고 와라. 다시 메인메소드의 정의를 살펴보자. 가장 먼저 읽어들인다는데 어디서 먼저 읽어드릴까? 바로 "명령프롬프트"창에서다 기억나는가? 시작할때 java Test1 이라고 입력해야 된다고 했던것을~ 여기 문자열을 읽을 필요가 있을때를 대비해서 고맙게도 자바는 이렇게 문자열 배열을 만들어 놓은 것인데 이해가 쉽도록 시작 명령어를 설명과 함께 다시 써보겠다.

java Test1 args[0] args[1] args[2]......

즉, 여러분이 처음 자바소스를 실행할때 파일이름 옆에다가 어떤 문자열을 파일이름 옆에 입력해 놓을수도 있는데 자바에서 이것을 스트링 배열의 요소인 args로 읽어다가 프로그램에 써먹을수가 있다. 그러나 평상시에 프로그램 시작시킬때 특별히 전달할게 없으므로 아무것도 쓰지 않으니 입력값을 넣는 메인메소드의 괄호안은 보통 비어있는 것이나 마찬가지라고 생각하면 된다. 지금은 처음이라 필요가 없겠지만 여러분들이 진정한 자바 프로그래머로 탄생(?)하게 될 역사적인 순간에 이런걸 써먹을수 있도록 자바신(?)께서 메인메소드를 통해 이미 준비해 놓으셨다는 사실을 상기만 하고 지금은 이해할 필요도 없고 다른거 공부해야되니 후딱 머리 비우기 바란다.^^

public은 저번에 설명해서 알겠고 static이 무엇인지 궁금한 이가 많을 것이다. 흔히 메소드 앞에 static을 붙이면 정적메소드라고 하는데 이 부분 때문에 자바를 웬만큼 하는 이들도 이 부분 특히 메인메소드의 static만 나오면 자신이 없어지는 이가 많은데 일단 사전적인 의미는 "static 고정된, 움직이지 않는" dynamic의 반대말이다. 다이내믹이 뭔가 역동적인데 반해 뭐 가만히 있어도 된다는 그런 뜻인가? 헐~ 바로 그거다. 뭔가를 할 필요가 없다는거다. 가만있어도 알아서 해준다는거다.

오늘의 마지막 이슈 그 이름도 유명하고 많은 이들을 자바 공포로 떨게 하고 있는 static을 통해 오늘의 데미를 장식할까 한다. 자바를 오래 공부한 이들도 상당히 이해하기 어려운 부분에 속하는 것이 메인메소드인데 풀어서 설명은 하겠으나 처음 보는 이들은 자바에 대한 개념(?) 자체가 정립되어 있지 않으므로 필자가 아무리 쉽게 설명하더라도 이해를 못할수 있다. 그럴경우 그냥 메인메소드는 이렇게 써야되는구나 생각하고 무조건 외워서 써라. 먼 훗날 필자의 설명이 가슴속에 자삘(feel?)로 꽂힐때가 있을 것이다.ㅎㅎ

다시 돌아와서... 뭐를 알아서 해주는걸까? 컴파일할때 알아서 클래스를 제약없이 마음껏 불러서 쓸수 있게 만들어 주는 공간이라고 알아두자. 그럼 평상시에 클래스를 쓰고 싶을때 어떻게 해야 쓸수 있는지를 알아야하는데 new 라는 키워드를 통해 클래스를 재정의해서 쓰게 되며 우리는 이를 "객체" 혹은 "인스턴스"라고 부른다.

그럼 여기서 우리가 위의 메인메소드에서 맨위의 Robot 클래스안에 있는 void method( )라는 메소드를 불러서 쓴다고 가정하자. 결과값은 넣어봐야 아는 것이니까 그걸 빼고 명령을 주는데 그러면 그냥 method( )를 치면 동작해야 하는데 작동하지 않는다. 자바에서는 클래스를 이용한 객체 생성을 통해서 메소드에 접근할수 있도록 만들어 놓았기 때문이다. 바로 이렇게 말이다.

Robot x = new Robot( );

바로 로봇 클래스를 이용한 객체 생성을 완료하였다. 유식한 말로 인스턴스화했다고도 한다. 여하튼 이 인스턴스의 이름은 x이다. 이제 메소드를 부를수가 있다. 뭐를 통해서? x라는 인스턴스를 통해서 이런 식으로 사용한다.

x.method( );

이런 식으로 다른 곳에 있는 메소드를 불러서 쓸수가 있다. 조금 공식화해서 보여주자면,

인스턴스 생성시는~

클래스 인스턴스이름 = new 클래스( );

인스턴스 부를때는~

인스턴스이름.메소드이름(입력값);

이렇게 되겠당~

왜 static 하다 말고 이걸 설명하는거야? 라고 묻는이가 있을 것이다. 여기까지 이해를 해야 설명이 가능하기 때문이다. static의 기능이 여러가지 있지만 여기서 이해할 부분만 짚고 넘어가겠다. 필자가 프로그램의 시작과 끝이 메인메소드에서 이루어진다는 것을 못이 박히도록 얘기했는데 기억나겄지? 메인메소드도 엄밀히 이야기하면 클래스안에 있는 것인데 그럼 시작할때 메인메소드도 객체생성을 한후 불러서 쓸수 있어야 하지 않겠는가? 그럼 프로그램 실행할때마다 메인메소드가 안에 들어있는 클래스를 객체 생성하라고 시키고 자바소스를 실행시켜야 할것이다. 이 얼마나 난감한 일인가? 그런데 알다시피 우리는 그냥 자바소스 컴파일한후(이때 자바소스를 읽어들일때 static의 존재여부에 따라서 메인메소드가 어디에 있는지도 찾아내는 것이다)에 객체생성 이런거 없이 그냥 자바 프로그램 실행해서 메인메소드 너무나 당연하다는듯이 작동시키고 있는데 고맙게도 이런 수고(?)를 덜어준 바로 그 황금같은 단어 static이 메인메소드 앞에 딱 붙음으로써 모든 자바 프로그래머들이 그런 번거로운 작업에서 해방되었다는 믿기힘든 전설(?)이 미국 실리콘밸리 어디에선가 전해오고 있다고 한단다.ㅎㅎ

public static void main(String[ ] args)
public static void main(String args[ ])
public static void main(String[ ] apple)
static public void main(String orange[ ])
static public void main(String[ ] tiger)
static public void main(String lion[ ])

메인메소드를 써봤는데 여섯개 중에 뭐가 틀렸을까?
모두다 정답이다. 허걱~ 그럼 강이가 답해설을 하겠다. 두근두근~ ^^
public이랑 static은 위치가 바뀌어도 전혀 상관이 없다.
args는 아까전에도 얘기했듯이 매개변수 이름일뿐 아무거나 써도 된다.
배열을 뜻하는 [ ]은 변수 앞이나 뒤나 어디에 위치해도 상관없다.
너무나 당연하지만 void main( )는 순서 절대 바뀌면 안된다.
이유는 메인메소드이니까 메소드 형식에 따라 "결과값 이름(입력값)"의 형식을 취한다.
여기서 필자가 추천하는 메인메소드 형식은 첫번째 구문이다.
public static void main(String[ ] args)
모든 명령어 의미 하나하나가 순서대로 빠르게 전달될뿐 아니라 깨끗하고 명료하니 여러분도 이렇게 쓰는데 익숙해지기 바란다.
더불어 메인메소드는 위와같이 항상 똑같은 형식이니 이번 기회에 그냥 외워버리자.

메인메소드 하나 가지고 이렇게 많은 내용을 일일히 설명하는게 어이없게 보일지도 모르겠으나 그 노력은 헛되지 않을 것이며 여기까지 소화하며 따라온 이들에게 필자는 경의를 표하고 싶다. 다시 강조(?)하지만 메인메소드 하나 가지고 울어먹은것 절대 아니다. 믿어달라.^^ 자바를 웬만큼 하는 이들도 메인메소드를 이 정도까지 독파하고 있는 이들은 상당히 드물 것이다. 여러분이 처음 자바를 시작했더라도 오늘 설명한 강좌를 확실하게 이해했다면 어느 누구에게도 웬만해서는 꿀리지 않는 자바 프로그래머의 첫 단추를 제대로 끼웠으리라 확신하면서 오늘은 여기서 끝내겠다. 수고 많았다. 쉬어라~ ㅎㅎ

댓글 13개:

  1. 와... 경의를 표합니다.

    너무너무 감사합니다.

    이해가 안되서 꽉꽉 막혔었는데..

    by, 타루

    답글삭제
  2. 잘보구 갑니당~

    -Carter24

    답글삭제
  3. 이해가 쉽게 글을 적어 주셔서 감사합니다~~~ ^^
    도움이 많이 되었어요

    답글삭제
  4. 큰 도움이 되었습니다. 진심 감사드리고 나머지 강좌도 조금씩 익혀보겠습니다.

    답글삭제
  5. 참 쉽게 잘 설명해 놓으셨네요.. 덕분에 잘 배우고 갑니다.

    답글삭제
  6. 어렵게 찾은 보물??을 주시다니 감사합니다.~^^

    답글삭제
  7. ㅜㅜ 감사합니다. 강의 너무 이해가 잘되네요!!

    답글삭제
  8. 정말 좋은 강의 잘 봤습니다. 폭풍감동 하나 투척.
    참고로 스트링은 줄인데요. 진주목걸이를 연상하시면 쉽습니다. 진주구슬이 주렁주렁 매달려 있잖아요? 문자들이 주렁주렁 매달려있으니 스트링이죠.

    답글삭제
  9. 강의 재밌게 잘 봤습니다

    다름이 아니라 강의를 보다가 궁금한 점이 생겨서 이렇게 글을 남기게 되었습니다

    보통 클래스 안에 Main을 호출하고 있는데요

    Main의 경우 어떤 클래스에서 호출을 하더라도 문제가 발생하지 않나요?

    그리고 Main이 어디에 선언되느냐에 따라서 메모리에 올라가는 순서도 달라질 것 같은데 아무 클래스에 선언하더라도 관계가 없는 건가요??ㅠㅠ

    답글삭제
    답글
    1. 메인 메소드는 프로젝트내 하나만 선언할 수 있습니다.
      프로젝트의 파일명 클래스에 메인메소드 1개 이외에는 전부 메인메소드에서 호출하여야 하며 메인메소드가 여러개가 있을 경우 오류를 내던가 메인메소드를 택일하라고 할 것입니다.
      프로젝트 파일명 클래스에 메인메소드가 없다면 메인메소드를 찾을 수 없다고 오류가 영어로 날 것이기 때문에 걱정안하셔도 됩니다.
      자바가 많이 까다로운 언어라 조금만 잘못해도 이거 해결해줘~ 빼액 거리며 오류를 뿜어내거나 실행시 오류를 뿜고 죽어요

      삭제
  10. 감사합니다 ㅋㅋㅋ ^^ 설명이 너무 좋았어요

    답글삭제