Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

이전장에서 자바프로그램이 만들어지고 실행되는 과정에 대해서 알아보았다. 이번 장에서는 간단한 예제 프로그램을 통해서 자바 프로그램이 샐행되는 과정을 좀더 자세히 알아보도록 하겠다.

다룰 내용들은 다음과 같다.
  • 간단한 예제 프로그램들의 작성
  • 소스파일과 클래스 파일의 이름
  • Syntax 에러 (문법 에러)
  • 버그
  • 편집, 컴파일, 실행의 사이클
  • Matching braces
  • Neat indenting
문제 다음 중 자바프로그램이 실행되기 위해서 필요한 파일은 무엇인가.
  • 소스 코드 파일
  • 바이트코드 파일

예제 소스 프로그램

이전장에서 다룬 소스프로그램을 가지고 설명하도록 하겠다. 이 프로그램은 모니터에 Hello World!를 출력하는 일을 한다.
class Hello
{
  public static void main ( String[] args )
  {
    System.out.println("Hello World!");
  }
}

이 파일은 반드시 Hello.java로 클래스의 이름과 같아야만 한다. 많은 컴퓨터 시스템이 파일이름의 대소문자를 구분하기 때문에, 대소문자도 분명히 구분해서 파일이름을 만들도록 하자. 소스 프로그램의 첫번째 라인을 보자 class Hello

이 소스프로그램은 Hello라는 클래스명으로 정의가 된다. class는 프로그램의 section을 결정한다. 작은 프로그램은 단지 하나의 클래스로 구성이 되기도 한다. 이 프로그램을 컴파일 하면, 컴파일러는 Hello.class라는 바이트코드 파일을 생성한다.

모든 클래스는 하나 이상의 여러 라인으로 구성이 되며, 클래스의 시작과 끝을 알리기 위해서 {}이 사용된다.

클래스의 이름은 반드시 알파벳과 숫자로 작성이 되어야 하며, 첫자는 알파벳을 사용해야만 한다. 이름의 중간에 공백등이 포함되면 안된다. 필수사항은 아니지만 관습적으로 클래스의 첫자는 대문자를 사용하는 경우가 많다. 확장자 이름은 소문자로 .java를 사용하면 된다.

문제 첫라인이 다음과 같은 자바 소스 프로그램이 있다. class AddUpNumbers
  1. 소스파일의 이름은 무엇인가
  2. 컴파일된 바이트코드 파일의 이름은 무엇인가.

Between the Braces

위에서 다룬 자바 프로그램은 다음과 같은 구성을 가지고 있다.
class Hello
{
...
}

클래스는 {로 시작하고 }로 끝을 맺으며, 모든 내용은 이들 괄호 사이에 존재한다. 지금은 단지 하나의 클래스만 가지는 간단한 프로그램만 다루고 있지만, 나중에는 여러개의 클래스를 가지는 프로그램도 다루게 될 것이다.
class Hello
{
  public static void main ( String[] args )
  {
    System.out.println("Hello World!");
  }
}

이 예제 프로그램은 Hello World!를 모니터에 출력한다. 정말로 간단한 프로그램이지만, 여기에는 자바 프로그램을 이해하기 위한 중요한 많은 요소들을 포함하고 있다. 첫번째 라인을 살펴보자.
public static void main(String[] args)
프로그램이 시작되는 지점이다. mainmain method라고 불리우는데, 자바 가상 머신이 프로그램을 실행시키는 지점이 된다. 모든 자바 프로그램은 실행이 되기 위해서 반드시 하나의 main 메서드를 가지고 있어야만 한다. 문제 다음은 main 메서드는 문제가 없는가 ? public static void main(Stringp[] args)

println

http://chortle.ccsu.edu/java5/Notes/chap06/ch06_4.html

예제 프로그램을 다시한번 살펴보도록 하자.
ass Hello
{
  public static void main ( String[] args )
  {
    System.out.println("Hello World!");
  }
}
이 프로그램의 메인 메서드는 다음과 같은 한줄의 코드를 포함하고 있다. System.out.println("Hello World!");

이 코드는 쌍따움표 안에 있는 문자를 컴퓨터 시스템의 모니터에 출력하는 일을 한다.

"Hello World!" 와 같이 문자가 연속되어있는 것을 string (혹은 문자열)이라고 부른다. 이 프로그램을 string를 모니터에 출력하고 프로그램을 종료시킨다.

문제 소스를 포함한 Hello.java 파일을 만들도록 하자. 이 프로그램을 실행시키기 위해서는 2가지 과정을 거쳐야 한다. 이에 대해서 논하라.

자바 프로그램의 실행 과정 다시보기

프로램을 실행시키기 전에 우선, 현재 작업중인 디렉토리에 소스파일이 있는지 확인해야 한다. 그래야 컴파일과 인터프리터 명령이 제대로 수행될 수 있다. 많약 다른 디렉토리에서 작업을 한다면 File Not Found와 같은 에러 메시지를 보게 될 것이다. 파일의 확인은 ls 명령을 이용하면 된다.
# cd /home/java 
# ls *.java
Hello.java
만약 파일이 존재하지 않는다면 다음과 같은 에러메시지를 출력할 것이다.
# ls *.java
ls *.java: 그런 파일이나 디렉토리가 없음

파일이 존재하지 않는다면 cd(1) 명령을 이용해서 소스파일이 있는 디렉토리로 이동하도록 하자. 그 후 javac를 이용해서 컴파일을 하고, 컴파일된 바이트코드를 java인터프리터로 실행시키면 된다.
# javac Hello.java
# java Hello
Hello World!
#

문제
  • 자바 컴파일러를 실행시키기 위한 명령은 ?
  • 자바 인터프리터를 실행시키기 위한 명령은 ?

문법 에러

아래의 소스 프로그램을 그대로 copy&paste 해서 Hello.java 로 저장한 후 컴파일 해보도록 하자.
Class Hello
{
  public static void main ( String[] args )
  {
    System.out.println("Hello World!");
  }
}
아마도 다음과 같은 에러메시지를 보게 될 것이다.
# javac Hello.java
Hello.java:1: 'class' or 'interface' expected
Class Hello
^
1 error
소스 코드는 이전의 코드와 동일해 보이지만 class의 첫자가 대문자C로 변경되었음을 알 수 있다. 이렇게 오타나 혹은 문법이 잘못된 것을 syntax error (문법에러)라고 한다.

컴파일러는 소스코드를 바이트코드로 변환하려고 하지만 Class라는 알 수 없는 문법을 만나게 된다. 컴파일러는 이경우 어떻게 변환해야 할지 알 수 없기 때문에, 에러메시지를 출력하는 것이다. 소스코드에 이러한 문법에러가 존재하는 한 절대로 바이트코드를 만들어 낼 수 없다. 문제 위의 예제 코드를 바이트코드가 만들어 지도록 수정해 보라.

문법에러 수정

Hello.java를 vi(:12)로 열어서 ClassC를 소문자로 변경한다음 저장한다. 이제 문제 없이 컴파일 될 것이다.

편집, 컴파일, 실행 주기

이번 장에서 당신은 당신이 만든 프로그램을 제대로 실행시키기 위해서 다음과 같은 주기를 거쳐야 한다는 것을 알게 되었다.
  1. vi를 이용해서 프로그램을 편집한다.
  2. 프로그램을 하드디스크에 저장한다.
  3. javac명령을 이용해서 프로그램을 컴파일 한다.
  4. 만약 문법에러 등으로 컴파일이 되지 않는다면 1번으로 되돌아 간다.
  5. java명령을 이용해서 프로그램을 실행한다.
  6. 제대로 실행되지 않는다면 1번으로 되돌아간다.
  7. 제대로 실행되면, 주기를 종료한다.
이것을 edit-compile-and-run 주기라고 한다. 하나의 프로그램을 작성하기 위해서는 이 주기를 몇번씩 순환해야 할 것이다. eclipse(:12)와 같은 자바 프로그램 개발환경을 이용하면, 이 주기를 숨길 수 있지만 (개발환경이 뒤에서 처리해 준다), 기본 주기는 변하지 않는다. 이 주기는 다른 언어를 이용한 개발에도 거의 동일하게 적용된다.

문제 주기의 3번째 차례에서 소스 프로그램의 컴파일이 성공했다면, 프로그램이 제대로 실행 될 것이라는 걸 의미하는가 ?

버그

프로그램이 제대로 컴파일 되고 실행되었다고 해서, 프로그램이 제대로실행되는 것은 아니다. 예를 들어서, 당신이 술을 마신상태에서 소스프로그램을 만든 다면 다음과 같은 소스 프로그램을 만들어 낼 수도 있다.
class Hello
{
  public static void main ( String[] args )
  {
    System.out.println("Hello Neptune!");
  }
}

이건 문법에러가 아니기 때문에, 컴파일되고 실행이 될 것이다. 그러나 Hello Neptune라는 얘기치 않은 string를 출력하게 된다. 이렇게 프로그램의 실행도중에 발생하는 얘기치 않은 문제를 bug(:12) 라고 한다.

문제
  1. 이 프로그램은 문법에러 없이 컴파일 되는가 ?
  2. 이 프로그램은 실행되는가 ?
  3. 이 프로그램은 원하는 결과를 보여주는가 ?

긴 프로그램의 작성

버그 없는 프로그램을 만드는 것은 거의 불가능하다. 아주 단순한 프로그램이라고 하더라도 몇개의 버그를 가지고 있을 수 있다. 문제는 심각한 버그인가 아닌가 하는 것이다. 프로그램의 크기가 커지면 당연히 더 많은 버그가 생길 수 있으며, 매우 주의 깊게 프로그램을 작성해야 한다. 문법오류와 버그는 많은 연습을 통해서 어느정도 줄일 수 있다. 또한 경험 많은 프로그래머는 찾기 어려운 버그도 쉽게 찾아낸다.

다음은 좀더 긴 예제 프로그램이다.
class Emily
{
  public static void main ( String[] args )
  {
    System.out.println("A bird came down the walk:");
    System.out.println("He did not know I saw;");
    System.out.println("He bit an angle-worm in halves");
    System.out.println("And ate the fellow, raw.");
  }
}
이 프로그램을 Emily.java로 저장하고, 컴파일 한 후 실행하고 결과를 확인해 보도록 하자.

문제 위 예제 프로그램의 실행결과를 예상해보라.

다른 예제

마지막으로 다음과 같은 string를 모니터에 출력하는 프로그램을 직접 만들어 보도록 한다. On a withered branch A crow has just alighted: Nightfall in autumn.

아래의 빈칸을 채워서 완성하면 된다.
class Haiku
{
  public static void main ( String[] args )
  {
    System.out.println(_______________________________);
    System.out.println(_______________________________);
    System.out.println(_______________________________);
  }
}

문제 위 프로그램을 완성한다음 실행시켜 보도록 하자.

프로그램의 종료

여기에 완전한 프로그램이 있다. 이 프로그램은 상따움표 안에 있는 string를 출럭한다. 아래의 코드를 에디터를 통해서 입력할 때, 오타만 없다면 문제 없이 컴파일되고 실행될 것이다.
class Haiku
{
  public static void main ( String[] args )
  {
    System.out.println("On a withered branch");
    System.out.println("A crow has just alighted:");
    System.out.println("Nightfall in autumn.");
  }
}

예제 프로그램을 입력하다보면, 여러개의 스페이스문자를 사용하거나 여러개의 개행문자를 입력할 수 있을 것이다. 그러나 이것들은 컴파일하는데 문제를 일으키거나 하지는 않는다. 아래의 예를 보기 바란다.
  class     Haiku{
  public   static void main(String[] args )
    {
  System.out.   println(          "On a withered branch");
    System  .  out.println("A crow has just alighted:"         );
System.out.println("Nightfall in autumn.");
  }}
코드가 꽤 난잡해지긴 했지만, 컴파일러는 무사히 코드를 번역해서 바이트코드를 생성해 낼 것이다. 인간의 눈에 보기에는 난잡한 코드지만, 위의 코드와 완전히 동일한 바이트 코드를 생성해 낸다.

비록 자바 컴파일러 입장에서는 스페이스나 개행문자를 별로 신경쓰지 않는다고는 하지만 소스 프로그램은 사람이 보기 좋게 작성해야할 필요가 있다는 것을 염두에 두기 바란다.

문제 프로그램에 사소한 실수가 있을 경우, 쉽게 문제를 찾아낼 수 있는가 ?

주석

주석 (comment)는 프로그램에 인간만이 해석하도록한 일종의 표시다. 아래의 프로그램은 주석을 사용한 예이다.

// Write three lines of a poem to the computer monitor
class Haiku
{
  public static void main ( String[] args )
  {
    System.out.println("On a withered branch" );
    System.out.println("A crow has just alighted:");
    System.out.println("Nightfall in autumn.");
  }
}
// 이후의 라인은 인간만이 해석하라고 약속되어 있으므로, 컴파일러는 이 줄을 건너 뛰게 된다. 그러므로 주석을 사용하지 않은 코드와 완전히 동일한 바이트코드를 생성하게 된다. 자바 컴파일러는 주석은 해석하지 않고 건너 뛴다.

문제 주석은 바이트코드로 변환되는가?

많은 주석의 작성

주석은 프로그램의 코드를 설명하기 위해서 사용된다.

class Haiku
{
  public static void main ( String[] args )
  {
    System.out.println("On a withered branch" );  // Write first line of the poem
    System.out.println("A crow has just alighted:");  // Write 2nd line of the poem
    System.out.println("Nightfall in autumn.");  // Write 3rd line of the poem
  }
}
// 주석을 사용하면 // 표시뒤의 문자들이 모두 주석으로 처리된다. 그렇다면 여러라인의 줄을 동시에 주석으로 사용하고자 경우도 필요할 것이다. 이 경우에도 //로 처리가 가능하겠지만, 보통 /* */을 널리 사용한다.

/* Program 1

Write out three lines of a poem.
The poem describes a single moment in time,
using 17 syllables.
*/

class Haiku
{
  public static void main ( String[] args )
  {
    System.out.println("On a withered branch" );
    System.out.println("A crow has just alighted:");
    System.out.println("Nightfall in autumn."); 
  }
}
이건 주석의 또다른 스타일로 /* */사이에 있는 모든 문자들을 주석으로 처리한다. 이 스타일은 주석의 양이 많아질 때 유용하게 사용할 수 있다.

문제 왜 당신의 프로그램에 사용된 주석은 프로그램을 이해하는데 도움을 주는가?

괄호문

프로그램을 보면 코드들이 괄호에 둘러쌓여 있음을 알 수 있다.
왼쪽괄호 
   {
오른쪽괄호
   }

예제 코드에서 첫번째 괄호는 클래스가 이제 시작됨을 나타내고, 두번째 괄호는 클래스가 여기에서 끝나고 있음을 알려준다. 또한 괄호는 그 안에 또다른 괄호를 둘 수가 있는데, 이 경우 메서드의 시작과 끝을 나타내기 위해서 사용한다.

class Haiku
{
  public static void main ( String[] args )
  {
    System.out.println( "On a withered branch" );
    System.out.println( "A crow has just alighted:" );
    System.out.println( "Nightfall in autumn." );
  }
}

끝내며

괄호는 시작괄호와 끝괄호가 서로 정확히 매칭 되어야 함을 기억하기 바란다. 이것은 ()와 같은 소괄호나, []등에도 그대로 적용된다. 이 괄호들은 프로그램에서 클래스나 메서드의 영역을 명확히 정의 하기 위해서 사용한다.
class Haiku
{
  public static void main ( String[] args )
  {
    System.out.println( "On a withered branch" );
    System.out.println( "A crow has just alighted:" );
    System.out.println( "Nightfall in autumn." );
  }
}