여러분은 public static void main(String[] args) 가 왜 static으로 선언되어 있어야 했는지 의문이 있었는가?
솔직히 나도 처음에는 관심을 안가졌었는데 오늘은 이상하게 눈에 띄어서 살짝 들춰봤다.
오라클 문서에는
"메인 메서드는 반드시 public, static, void로 선언하고, 그 매개변수는 String 배열 타입으로 선언해야 합니다." 라고 써져있다.
아래 내용을 진행하기전에 우리가 알아야할 배경 지식을 알려주겠다.
참고)
프로그램을 작동시키기 위해 JVM이 처음으로 부르는 시작점은 main 메소드이기 때문에 main 메소드를 부를 때 JVM은 정말 아무것도 없는 빈털털이로 객체 생성이 아무것도 없는 상태에서 호출하고 있고 객체 생성을 하지도 못하고 있다.
결론부터 말하자면, 객체 생성 없이 프로그램을 실행할 수 있어야 하기 때문에, 클래스 레벨에서 이름만으로 직접 호출 가능한 메소드로 static으로 선언 되어야 한다.
객체가 무엇인데? 객체 생성은 어디에서 이루어지는데? 우선 근본적인 것부터 해결해보자.
위의 나온바와 같이, 제임스 고슬링이 작성한 자바 언어 설명서 (The java Language Specification)에는 객체(object)란 클래스의 인스턴스나 배열을 말한다고 정의되어 있다.
우리가 코드상에서 객체를 만든다고 한다면 흔히 new 선언을 통해 생성해준다.
new로 선언한다고 하니 참조자료형이 생각나지 않나?ㅎㅎ 즉, 객체는 힙메모리에 저장된다.아래 자료에서도 힙에 할당된다고 써져있다.
클래스에서 객체를 만들기 때문에 클래스가 로드 된 후에야 객체 생성을 시작할 수 있다.
자바 애플리케이션이 시작되면 JVM은 클래스 파일을 로드하고, 메소드 영역(Method Area)에 클래스의 static 필드와 메소드등의 클래스 정보를 저장한다. 그리고 정적 초기화가 진행된다 (초기화 과정에서 필요한 값들이 메소드 영역에 저장된다)
이 시점에 인스턴스 생성은 발생하지 않기에 힙 메모리나 스택 메모리는 사용되지 않는다.
JVM이 프로그램 시작점으로 main 메소드를 찾는다. main 메소드는 static으로 선언되어 있기 때문에 인스턴스가 없어도(객체 생성없이도) JVM이 main 클래스를 메모리에 로드하고 호출할 수 있다.
main 메소드가 호출되면, 클래스가 메로리에 로드 되었기 때문에 그 안에서 이제 객체 생성이 시작된다. 이제 힙과 스택 메모리가 사용되기 시작하는 것이다. 프로그램이 본격적으로 실행된다.
이를 통해 우리가 알 수 있는 점을 정리하자면, 객체 생성 및 할당을 힙메모리에서 하지만, main 메소드를 호출하기 전에는 JVM이 주로 메소드 영역에만 접근하여 프로그램을 준비하기 때문에 main 메소드 호출전에는 객체 생성을 못한다는 말이며, static으로 메인 메소드를 선언을 해야 객체 생성 없이 클래스 자체에서 main 메소드를 호출할 수 있다는 것을 알 수 있다.
참고) 오라클 문서