[Java] 왜 main()에 들어가는 인자는 오직 String 배열 뿐일까?
자바에서 프로그램을 코딩하기 위해 가장 먼저 입력하는 코드가 있다.
public class Example {
public static void main(String[] args) {
...
}
}
바로 이놈인데, 왜 String[] args
를 쓰는지 알 길이 없었다. 처음에는 그냥 받아들였는데, 곰곰이 생각해보니 대체 이놈의 정체가 무엇인가!
main()
이 필요한 이유는 → 자바 클래스에서 main()
이 엔트리 포인트기 때문이다. (항상 main()
부터 실행된다).
근데 왜 String[] args가 필요하지?!
Java 클래스로 프로그램을 실행할 때, JVM은 길이가 0인 String 배열
을 먼저 생성한 다음 main() 메소드를 호출할 때 매개값으로 이 배열을 전달한다.
String[] args = { }; // 요놈을
public static void main(String[] args) {
//이 메소드 호출 시 위의 main() 메소드 안의 파라미터로 전달한다.
...
}
만약 빈 배열이 아니라 main()에 파라미터를 전달하고 싶다면? 그냥 넣어주면 된다!
String[] args = { 문자열0, 문자열1, 문자열 2, ... 문자열n-1 };
public static void main(String[] args) {
...
}
main()
메소드는 String[] args
매개변수를 통해서 커맨드 라인에서 입력된 데이터 수(배열 길이)와 입력 데이터(배열 항목 값)을 알 수 있다.
실험 1: 만약 main()
에 인자를 아무 것도 넣지 않으면?
결과: 실행 자체를 할 수 없다..
실험 2: 만약 main()에 String[] 이 아닌 다른 배열을 넣으면? (int[]
)
역시 실행이 안된다..
Why command line arguments are only string in java?
궁금해서 검색을 때려봤다. 아래처럼 검색해보니, 재밌는 내용을 발견했다.
why command line arguments are not integer in java
why command line arguments are only string in java
Java에서 main()에 들어가는 인자를 명령행 인자(command-line arguments)라고 한다. 이 명령행 인자는 반드시 자바 프로그램 외부에서 들어올 수밖에 없다. 만약 외부에서 integer 타입이나 Object 타입 등이 들어온다고 생각해보자. 이게 어떻게 들어올 수 있을까?
- Object 타입이 만들어지려면 반드시 자바에서 코드를 짜야 한다. 근데 main() 메소드는 엔트리 포인트, 즉 가장 먼저 실행되는 메소드이니 그 이전에 어떤 코드도 실행이 되지 않는다. 따라서 Object 타입은 main()의 인자로 들어올 수 없다.
- 그럼 Integer 타입은 가능하지 않나? 놉. 명령행, 즉 커맨드 라인에서 받는 값은 전부 String에 해당한다. 백준 문제 풀 때 생각해보자. 프로그램이 인자로 받는 값은 String이고 이걸 Integer로 변환하는 작업을 거친다. 애초에 명령행에서 받을 수 있는 값이 String 뿐인 것.
그러면 C/C++ 처럼 void에서 아예 인자 자체를 받지 않을 수도 있지 않나? 이건 자바 언어의 철학에 해당한다. 아래 인용문을 읽어보자.
자바 코드를 빌드하면 bin 안에 바이너리 파일들이 생성되거나 jar 파일로 압축하여 추출해낼 수 있는데요. 이 때 커맨드 창에서 자바 프로그램을 실행하면 작성하신 프로그램이 실행됩니다.이 때 실제 진입하여 시작되는 파일이 main 메소드가 있는 파일입니다.
main 말고 다른 메소드는 main 내나 다른 메소드 내에서 호출됩니다. 그래서 다른 메소드를 호출할 때 파라미터로 넘겨주는 값을 함수가 호출되기 전에 프로그램 소스코드 상에서 값을 정의해서 넣어줄 수 있습니다.
하지만 main은 가장 먼저, 최상위 레벨에서 호출되는 메소드입니다. 그래서 소스코드로 main 메소드가 받을 수 있는 파라미터의 내용을 정해줄 수 없습니다. 프로그램이 시작만 하면 무조건 main 부터 시작하기 때문이죠. 게다가 다른 메소드에서 main 을 호출하는 것도 불가능합니다. "프로그램 내부에서 값을 호출할 수가 없으며, 이렇기 때문에 항상 문자열 인자를 받게됩니다."는 소스코드 상에서 프로그래머가 원하는 대로 main 메소드 매개변수를 원하는 대로 넣어줄 수 없기 때문에 실행 시작 시점에 외부에서 인자로 받게 한다는 의미인 거죠.
그런데 간혹 우리는 프로그램 시작하면서 명령줄에 인수를 넣어줘야 하는 경우가 있습니다.(특히나 중간에 사용자 입력을 받거나 할 수 없는 배치성 프로그램 같은 걸 쓰면 거의 100% 확률로 써야 될 겁니다) 프로그램 시작과 동시에 사용자가 데이터를 넘겨주려면 그렇게 해야 하니까요. 그렇기 때문에 main 메소드가 args라는 변수를 파라미터로 받는 것입니다. 참고로 배열형인 이유는 매개변수가 여러개일 수도 있기 때문에 그렇게 합니다.
(C/C++ 에서는 void main() 을 허용하기 때문에 이 두 언어를 먼저 배우신 분들은 자바에서는 왜 반드시 String[] args 를 줘야 하나 생각하실 수 있는데, 자바의 언어 철학에 따라서 그렇게 디자인한 겁니다.매개변수를 반드시 정의하고 나중에 호출할 때 안 쓰면 그만이라고 하는 쪽이, 매개변수를 못 받는 main 을 정의하는 것을 허용하는 것보다 덜 헷갈린다고 자바의 창시자들이 생각했기 때문인 것이죠.
언어마다 나름대로 창시자의 철학이 있기 때문에 비교하는 것도 재미있는 일입니다.)
참고한 사이트 링크는 아래와 같다.
Reference
- <이것이 자바다> ch. 5
- https://www.baeldung.com/java-command-line-arguments
- https://stackoverflow.com/questions/20207913/why-only-string-args-in-java-instead-of-object-args
- http://courses.cms.caltech.edu/cs11/material/java/donnie/java-main.html
- https://www.journaldev.com/12552/public-static-void-main-string-args-java-main-method
- https://kephilab.tistory.com/40
- https://okky.kr/article/993250?note=2421298