안녕하세요 코북입니다. Java에서 클래스를 생성하려고 하면 main메소드를 만들 것인지 물어보는데, 항상 무지성으로 만들어왔지만 무슨 뜻을 가지고 있는지 정확히는 몰랐던 것 같습니다. 그래서 오늘은 public static void main(String[] agrs)의 의미를 알아보려고 합니다.
1. public
OOP에서 접근제한자는 데이터를 보호하기 위해 다른 객체의 접근을 제한하기 위해 사용한다. public은 바로 접근 제한자 중 하나이다. 제약이 강한 순서대로 private → protected → public이 있으며,
public은 어느 곳에서든 해당 객체를 참조할 수 있다는 의미이다.
즉, public은 '공개한다' 라는 뜻이고, 열려있으니 외부 클래스가 자유롭게 사용할 수 있다.
그런데 main함수에서는 public을 꼭 지정해줘야한다.
왜 그럴까?
main 함수는 모든 실행 프로그램의 기본이 되는 함수이기 때문에 어디에서나 접근이 가능해야 한다.
main 함수 제한자가 public이 아니면 main 함수에 접근하지 못하는 클래스가 있을 수 있고 그런 경우가 발생하면 안 되기 때문에 public으로 선언해야 한다.
2. static
Java는 변수나 함수를 메모리에 할당하는 방법이 2가지가 있는데, 첫 번째는 static영역에 선언하는 것이고, 다른 하나는 heap 영역에 선언(new연산자)하는 것이다. static과 heap을 비교해보면
1. static영역은 프로그램이 실행되는 순간 메모리가 할당되지만, heap영역은 연산이 실행되는 순간 메모리가 할당된다. 2. static영역은 메모리 정리 대상이 아니지만, heap영역은 JVM의 Garbage Collector에 의해 정리된다.
main메소드가 heap영역에 선언되면 어떻게 될까?
위에서 말했듯이 main메소드는 프로그램에 없어서는 안 되는 기본 함수이다.
이 함수가 Garbage Collector에 의해 메모리에서 정리되면 어떻게 될까?
기본이 되는 함수가 정리되니 프로그램이 죽게 된다.
따라서 static으로 선언하여 메모리에 항상 상주하도록 설정해야 한다.
3. void
void는 "함수가 끝날 때 리턴 값이 없다"라는 의미이다. 일반 함수는 void를 사용해도 되고, int, char 등 다른 타입을 사용해도 문제없이 동작한다.
그런데 왜 main함수는 void여야 할까?
이유는 위에서도 말했지만 main함수가 종료되면(혹은 비정상적으로 죽으면) 프로그램이 종료된다. 프로그램 자체가 종료되기 때문에 return값의 의미를 지닐 수가 없다. 반면, 일반 함수의 경우 정상적 혹은 비정상적인 경우 리턴 값을 변수에 담아 다음 단계를 진행할 수 있다. 그래서 main함수는 void를 의무적으로 사용해야 하고 return값을 가지기 위해 void대신 다른 타입을 사용하는 경우 에러가 발생한다.
또한 main 자체가 하나의 프로그램의 시작과 끝인데, 프로그램 자체가 종료되는 시점에서 어떤 특정 값이 반환되는 것이 의미가 없기 때문이다. 어떤 계산에 의한 값의 반환이 있다면 그건 어디까지나 프로그램이 종료되기 전에 이루어져야 하고, 그 반환된 값 역시 프로그램이 종료되기 전에 사용되어야 정상적인 것이므로 프로그램의 시작과 끝이 함께하는 main메소드에는 반환 값이 없는 void를 사용해야 한다.
4. main()
Java의 시작(Entry Point)은 main함수명으로 시작해야 한다. 모든 자바 애플리케이션 프로그램에 꼭 들어가야 하는 문장이며, 컴파일하여 실행시킬 경우 자바 런타임 인터프리터가 제일 먼저 이 main() 메소드를 찾아 실행을 한다. main() 메소드는 "String[] agrs"라는 한 개의 파라미터 값을 갖도록 정의되어 있고, agrs는 실행시의 클래스에 전달되는 커맨드 라인 인자로서 String의 배열형으로 정의함으로서 여러개의 문자열을 받아들일 수 있다. 쉽게 말해 자바 애플리케이션 프로그램을 자바 인터프리터로 실행할 경우 실행 명령 뒤에 문자열을 인자로 줄 수 있는데 이것을 받아들이는 String형 배열이다.
5. String[] agrs
이것에 대해 더 자세히 이해해보자. agrs 문자열을 배열로 사용하겠다 라는 의미이다. agrs는 변수명이기 때문에 꼭 agrs가 아니어도 상관은 없으나, String[] agrs 구문 자체를 뺄 수는 없다.
왜 그럴까?
모든 함수는 매개변수를 사용할 수도 있고 사용하지 않을 수도 있다. 일반 함수는 main함수 내부에서 호출하기 때문에 입력값을 main함수 안에서 정할 수 있다. 그러나 main함수는 프로그램 실행 시 처음으로 수행되는 함수이기 때문에, 외부로부터 값을 입력받을 수 있어야 한다. 프로그램 내부에서 값을 호출할 수 없기 때문에 항상 문자열 인자를 받게 된다.
예를 들어 Test.class라는 이름으로 클래스를 생성하고 실행한다면, java Test.class라는 명령어를 통해 실행이 되는데, java Test.class "abc" "def" 이런 식으로 맨 처음 프로그램이 실행하는 순간 특정한 값을 입력하고자 하는 경우, 그렇게 입력한 "abc" "def"가 String타입의 배열 agrs[0], agrs[1]에 저장이 되어 프로그램 안에서 사용할 수 있게 된다.
이렇게 사용하는 것을 매개변수라고 하는데, main에서 String[] agrs라고 선언을 하는 이유는 프로그램의 실행 순간 외부 값을 가져와서 프로그램 안에서 사용하고자 할 때 메모리에 저장할 공간을 미리 선언해 두는 것이라고 할 수 있다.
배운 점
Java를 사용한 지 반년이 넘었지만 main메소드에 대해 처음 찾아본 것 같다. 흔히들 공부를 시작할 때 가장 중요한 것은 기초라고 말하지만, 그만큼 가장 놓치기 쉬운 것도 바로 기초인 것 같다는 생각이 든다. 빠르게 배우고 개선해 나가는 것도 중요하지만 더 중요한 것이 무엇인지 고민해 볼 필요가 있을 것 같다.
본 글은 아래 링크의 내용을 참고하여 학습한 내용을 나름대로 정리한 글임을 밝힙니다.
https://it-mesung.tistory.com/m/84
'Java' 카테고리의 다른 글
[error/Java]Implicit super constructor Unit() is undefined. Must explicitly invoke another constructor (0) | 2022.01.31 |
---|---|
[error/jsp] duplicate local variable (0) | 2021.08.04 |
[JDBC/Oracle] Java에서 DB연결 (1) | 2021.08.02 |