본문 바로가기

Java/Chapter 10. 클래스 변수와 클래스 메소드

[Java] 10.03 - System.out.println() & public static void main()

들어가며

 지금까지 main 메소드를 정의할
때 그 앞에 static 선언을 붙여왔다.

 그리고 인스턴스의 생성 없이
println 메소드를 호출해 왔다.

 어케했ㄴ노

 

System.out.println()에서 out과 println의 정체는?

 static 선언의 의미를 알았으니,

 System.out.println의 구성을
이해할 수 있다.

 일단 System은 자바에서 제공하는
클래스로, java.lang 패키지에 묶여
있다.

 따라서 원칙적으로는 다음과 같이
호출하는 것이 맞다.

java.lang.System.out.println( . . . );

 그러나 컴파일러가 다음 문장을
삽입해주기 때문에

 패키지의 이름 부분을 생략할
수 있다.

import java.lang.*;    // 컴파일러가 삽입하는 import 선언

 그리고 out은 System.out으로
접근을 하니,

 이는 분명 static으로 선언된
클래스 변수가 분명하다.

 클래스의 이름을 통해 접근하니
말이다.

 실제로 out은 System 클래스
내에 다음과 같이 선언된
클래스 변수이다.

아래에서 System 클래스에 final 선언이 붙어 있는데 이것이 갖는 의미는 '상속'에서 설명한다.
public final class System extends Object{
    public static final PrintStream out;    // 참조변수 out
     . . .
}

 마지막으로 println은,

 PrintStream 클래스의 인스턴스
메소드이다.

 따라서 다음 문장을 보면서,

System.out.println( . . . );

 다음과 같이 이해할 수 있어야 한다.

System에 위치한 클래스 변수 out이 참조하는 인스턴스의
println 메소드를 호출하는 문장

 

main 메소드가 public이고 static인 이유는?

 main 메소드는 반드시 다음의
모양새를 갖춰야 한다.

public static void main(String[] args){
    . . .
}

 이렇듯 main 메소드는 public으로
그리고 static으로 선언해야 한다.

 이는 일종의 약속이며, 이러한
약속에 근거하여 다음과 같이
실행을 하면,

C:\JavaStudy>java MyMainClass

 MyMainClass에 public으로 그리고
static으로 선언된 main 메소드를
찾아 실행하게 된다.

public static void main(String[] args)

 main 메소드의 호출이 이뤄지는
영역은 클래스 외부이다.

 따라서 public으로 선언하는 것이
타당함을 알 수 있다.

 그리고 main 메소드는 인스턴스가
생성되기 이전에 호출된다.

 따라서 static 선언을 하는 것이
옳음을 알 수 있다.

 

main 메소드를 어디에 위치시킬 것인가?

 다음의 main 메소드가 호출이
되어 실제 실행이 되게 하려고
한다.

public static void main(String[] args){
    Car c = new Car();
    c.myCar();
    Boat t = new Boat();
    t.myBoat();
}

 그래서 이를 위해 다음과 같이
Car 클래스와 Boat 클래스가
존재한다는 사실만 중요하다.

class Car{
    void myCar(){
        System.out.println("This is my car");
    }
}

class Boat{
    void myBoat(){
        System.out.println("This is my boat");
    }
}

 이로써 main 메소드의 호출
준비는 끝이 났다.

 그렇다면 main 메소드는 어디에
두어야 할까?

 가장 먼저 생각할 수 있는 것은
main 메소드를 담을 목적으로
별도의 클래스를 정의하는 것이다.

 그러나 main 메소드는 static
메소드이기 때문에,

 즉 특정 인스턴스의 멤버로
존재하는 메소드가 아니기
때문에,

 다음과 같이 Car 클래스에
두어도 된다.

class Car{
    void myCar(){
        System.out.println("This is my car");
    }

    public static void main(String[] args){
        Car c = new Car();
        c.myCar();
        Boat t = new Boat();
        t.myBoat();
    }
}

class Boat{
    void myBoat(){
        System.out.println("This is my boat");
    }
}

 main 메소드를 Car 클래스
내에 위치시켰는데

 그 안에서 Car 인스턴스를
생성하고 있다.

 혹시 이부분이 조금 난해하게
느껴지는가?

 그럼 다음과 같이 생각하자.

Car 클래스와 static으로 선언된 main 메소드는 사실상 별개이다.
&
다만 Car 클래스가 main 메소드에게 공간을 제공했을 뿐이다.

 실제로 Car 인스턴스와 그 안에
정의된 클래스 메소드인 main과는
관계가 없기 때문에

 위와 같이 이해하는 것도 괜찮다.

 이제 실행을 해야 하는데 main
메소드가 Car 클래스 안에 있기
때문에

 다음과 같이 실행해야 한다.

C:\JavaStudy>java Car

 물론 Car 클래스를 대신해서
다음과 같이 Boat 클래스에
main 메소드를 두어도 된다.

class Car{
    void myCar(){
        System.out.println("This is my car");
    }
}

class Boat{
    void myBoat(){
        System.out.println("This is my boat");
    }

    public static void main(String[] args){
        Car c = new Car();
        c.myCar();
        Boat t = new Boat();
        t.myBoat();
    }
}

 위와 같이 main 메소드를
Boat 클래스에 두면

 다음과 같이 실행 방식에서
차이가 발생하는 것은 당연하다.

C:\JavaStudy>java Boat

 그리고 추천하는 방법은 아니지만
두 클래스 모두에 main 메소드를
두어도 된다.

 그러면 다음과 같이 2가지 방법으로
main 메소드의 호출이 가능하다.

C:\JavaStudy>java Car
C:\JavaStudy>java Boat

 사실 위의 상황에서 main 메소드를
담기 위한 별도의 클래스를 정의하는
것이 일반적이다.

 그러나 상황과 프로그래머의
성향에 따라서 다양한 형태의
코드가 존재할 수 있다.


참고 및 출처

윤성우의 열혈 Java 프로그래밍
국내도서
저자 : 윤성우
출판 : 오렌지미디어 2017.07.05
상세보기