Java

[Java] 왜 main()에 들어가는 인자는 오직 String 배열 뿐일까?

Woonys 2022. 5. 24. 11:43
반응형

자바에서 프로그램을 코딩하기 위해 가장 먼저 입력하는 코드가 있다.

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

반응형