어느날 동료가 내가 물었다. "왜 Java에서 main 메서드는 public static 일까요?" 나는 순간 제대로 대답을 하지 못했다. 이제껏 생각을 해본 적이 없기 때문이다.
나는 여태껏 main 메서드를 선언할때 public static void main(String[] args)라고 적는 것은 Java를 실행함에 있어 하나의 약속이라고만 생각했다.
하지만 다시 생각해보니 그렇게 하는데는 이유가 있을 것이라고 생각했다. 그래서 왜 이렇게 선언을 하는지 찾아보았다.
public static을 붙이는 이유?
1.접근제어자 public 이란?
- Java에서 접근 제어자의 종류는 private, default, protected, public이 있습니다.
1) private : 같은 클래스 내에서만 접근이 가능합니다.
2) default : 같은 패키지 내에서만 접근이 가능합니다.
3) protected : 같은 패키지 내에서, 그리고 다른 패키지의 자손클래스에서 접근이 가능합니다.
4) public : 접근 제한이 전혀 없다.
이와 같이 public은 접근제한이 없기 때문에 프로그램 시작점인 main 메서드에 접근 제한을 두지 않기 위해 public을 붙였습니다.
2.static이란 무엇인가?
static은 '클래스의' 또는 '공통적인'의 의미를 가지고 있다.
- 책에서는 다음과 같이 설명이 되어 있다.
제어자 | 대상 | 의미 |
static | 멤버변수 |
- 모든 인스턴스에 공통적으로 사용되는 클래스변수가 된다. - 클래스변수는 인스턴스를 생성하지 않고도 사용 가능하다. - 클래스가 메모리에 로드될 때 생성된다. |
메서드 |
- 인스턴스를 생성하지 않고도 호출이 가능한 static 메서드가 된다. - static메서드 내에서는 인스턴스멤버들을 직접 사용할 수 없다. |
위의 설명대로 static 메서드는 클래스 로딩 시점에 생성이 되기 때문에 객체 생성없이 호출이 가능합니다. 그래서 main 메서드는 Java 프로그램 시작점이기 때문에 객체생성 없이 바로 접근하기 위해 static을 붙입니다.
- 참고 : 위 내용은 남궁성,「Java의 정석」, 도우출판 을 참고 하였습니다.
왜 하필 main일까?
이 질문에 대한 답을 찾던 도중 한 stack overflow의 글 중 하나를 찾게 되었다. 거기에 적혀있는 설명대로 JVM이 최초 실행되는 클래스의 이름 main으로 정의해 놓았다.
실제로 Java 설치 후 생성되는 jdk 폴더의 src.zip 파일에 java.c 라는 파일을 열어보면 그렇게 정의되어 있다. 시간이 된다면 한번 열어보길 바란다.
mainID = (*env)->GetStaticMethodID(env, mainClass, "main", "([Ljava/lang/String;)V");
tomcat에서의 main
이번에는 웹 어플리케이션은 어떻게 동작이 되는가? 라는 궁금증이 생겼다. 나는 main 메서드를 생성하지 않았지만 웹 어플리케이션은 잘 동작한다. 그래서 이유를 찾아보았다.
- 우선 tomcat을 기준으로 설명하겠다. 답은 의외로 간단했다. tomcat이란 Servlet 컨테이너 위에 올라가서 동작하기 때문이다. 그래서 프로그램을 실행하고 우리의 비지니스 로직을 수행할 수 있다.
- 좀 더 자세히 살펴보면 tomcat의 구동은 startup.sh -> catalina.sh -> Bootstrap.java 순으로 이루어 진다. 세번째 Bootstrap.java 파일 안에 보면 main 메서드가 정의되어 있다. 그렇다 이 main 메서드를 이용해 tomcat을 구동시키는 것이다.
아래 두분의 블로그의 글을 보면 tomcat의 동작방법에 대한 설명이 잘 나와 있다. 좀 더 자세한 설명을 원하면 참고 하길 바란다.