JAVA May 07, 2021

java-operation

Words count 6.9k Reading time 6 mins.

public static void main(String[] args) 메인의 의미는 무엇인가??


static 이 무엇인지 void는 무엇인지 하나 하나의 특성을 알아가면서 정작 코딩을 할 때는

왜 이렇게 하지? public class ABCD { 왜 여기에는 static 을 안붙이고 void는 왜 안붙이지? 라는 생각을 매번 했습니다….ㅠㅠ

그러다 결국 이클립스에서 하는 main + space 를 누르면 항상 자동완성 되는 public static void main(String[] args)

이 부분에 대해서 검색해봤습니다.

결국에 찾다가 상당히 좋은 글을 보았기에 출처와 함께 퍼왔습니다.

초보자인 저에게는 상당한 도움이 되는 글이니 혹여나 다른 초보자분들도 보셨으면 이해가 쉽게 되실거라 생각됩니다!


일단 가장 중요한 public static void main(String[] args)부터 이야기 하는데

그 전에 그 밑의 public, static, void 등에 관해 먼저 읽고 오는걸 추천한다.

일단 Java에서 main이 가지고 있는 의미부터 이야기를 해야 할 텐데,

Java에서 얼마나 길고 많은 내용을 포함하고 있던지 간에,

무조건 다른 부분에 앞서 제일 먼저 시작하는 시작점(Entry Point)이 있다.

그 시작점의 역할을 하는 부분이 바로 main인데,

다른 클래스, 메소드를 인스턴스화 하던 멀 하던

메인에서부터 시작되지 않으면 의미가 없는 것이고,

Java에서는 결국 메인에서 시작해서 메인에서 끝난다는 정도만 알면 될 듯 하다.

그럼 그 main을 실행하는 데 있어 메인에서 다른 클래스 메소드 등을 호출해서 사용하는데,

막상 main 자체가 다른 곳에서 접근을 허용하지 않는다면, 문제가 생길수 밖에 없기에

가장 넓은 범위로 접근을 허용하는 public을 사용하는 것이다.

public이 아닌 protected나 private로 지정할 경우 타 클래스로 부터의 접근에 문제가 생겨

가장 중심이 되어야 할 main으로서의 기능 자체를 상실하게 되는 것이다.

또한 static을 명령어로 지정하는 이유는,

static의 특징이 프로그램이 시작하면서 따로 인스턴스 하지 않아도

프로그램의 시작과 동시에 static으로 선언된 것들은 메모리에 호출이 되어 지는데,

이렇게 호출된 것들은 다른 녀석들과는 다르게 프로그램이 종료되는 시점까지 계속 유지가 된다는 점이다.

다른 클래스, 메소드, 변수 등의 경우 Java Virtual Machine의 Garbage Collector에 의해

인스턴스화 되어 사용이 되어진다 하더라도, 일정 용도를 끝 마친 후에는 다시 메모리에서 삭제가 되거나,

다른 부분에서 참조가 되지 않는 부분 등이 있는데,

static으로 선언된 것은 끝까지 살아남아 계속 참조를 할 수 있는 특징이 있으므로,

프로그램에서 시작과 끝을 함께하는 main 메소드가 일정 시간만 살아있고 폐기되어서는 곤란하므로

계속 살아남아 역할을 하기위해서는 static 명령어가 꼭 필요하다고 할 수 있다.

void의 경우 메소드에 return 값이 없다는 뜻인데, main에서 void를 사용 하는 것은

main 자체가 하나의 프로그램의 시작과 끝인데,

프로그램 자체가 종료가 되는 시점에서 어떤 특정 값이 반환된다 한들 그 값이

의미를 가질리도 없고, 의미를 가져서도 안 된다.

어떤 계산에 의한 값의 반환이 있다면 그건 어디까지나 프로그램이 종료 되기 전에 이루어져야 하고

그 반환된 값 역시 프로그램이 종료되기 전 사용이 되어야 정상적인 것이므로

프로그램의 시작과 끝이 함께하는 main 메소드에는 반환값이 없는 void가 필요하다.

다음으로 String[] args가 있는데

여기 쓰이는 String은 우리가 흔히 사용하는 그 String과 같은 녀석으로 []를 통해 배열로 생성이 된다는 의미이다.

args의 경우 일반적으로 이렇게 사용할 뿐 원한다면 그 이름은 얼마든지 다른 것들로 대체할 수 있다.

String[] aabb 역시 성립한다는 의미이다.

또한 배열의 특징상 String args[] 역시 사용 가능하다.

이 명령어는 맨 처음 프로그램을 실행하는 데 있어

외부에서 값을 받아오기 위해서 사용하는 것인데,

예를 들어 Example01.class라는 이름으로 클래스를 생성하고 실행한다면,
java Example01.class 라는 명령어를 통해 실행이 되는데,

java Example01.class 100 200 이런 식으로 맨 처음 프로그램을 실행하는 순간 특정한 값을 입력하고자 할 경우

그렇게 입력한 100 200이 String 타입의 배열 args[0], args[1]에 저장이 되어

프로그램 안에서 사용할 수 있다는 것이다.

이렇게 사용하는 것을 매개변수라고 하는데,

main에서 String[] args라고 선언을 하는 이유는

프로그램의 실행 순간 외부값을 가져와서

프로그램 안에 사용하고자 할 때 메모리에 저장할 공간을 미리 선언해 두는 것이라고 할 수 있다.

습관적으로 늘 맨 앞에 붙이는 이 public 이란 녀석은 기본적으로 접근 권한에 관한 이야기를 말한다.

‘접근제어자’라는 이름으로 통합하여 이야기 할 수 있는데

이 접근제어자에는 public을 포함할 뿐 아니라 다양한 접근제어자가 존재한다.

public을 이야기하는데 빠뜨릴 수 없는게 [public, protected, private, (default)] 라는 녀석들이고,

이 녀석들 뿐만 아니라 [static, final, abstract] 등 도 상황에 따라 접근제어자로 구분이 될 수 있을 듯하다.

static을 포함한 녀석들은 아래에 다시 언급할 예정이니 넘어가고 위에 있는 4가지를 가지고 이야기를 해야겠다.

일단 public, protected, private, (default) 이렇게 4가지가 세트인데

모두 클래스, 메소드, 변수, 필드의 앞에 붙어서 선언 가능한 녀석들이다.

다만 이 중 (default)는 클래스, 메소드, 변수 등의 앞에 default 라고 쓰면서 사용이 되는게 아닌,

맨 앞에 아무것도 쓰지 않은 (공백)의 상태를 의미하는 점 주의하면 된다.

이걸 클래스 앞에 붙이느냐, 메소드 앞에 붙이느냐, 변수 앞에 붙이느냐, 필드 앞에 붙이느냐에 따라

각각의 용도가 조금씩 차이가 나는데, 기본적인 내용 자체에는 크게 차이가 없으니

세부적인 내용은 아래 위에 추천한 사이트에 방문하여 보도록 하고,

간단한 내용만 적어보자면,

public은 어디서나 상속 및 참조가 가능하다는 의미이다.

protected는 같은 패키지의 내부 혹은 이 클래스를 상속한 클래스에서만 접근을 허용한다는 의미이다..

private는 오직 이 클래스를 포함하고 있는 클래스 내부에서만 상속 및 참조를 허용한다는 의미이다.

(default)는 같은 패키지 내에서만 상속 및 참조가 가능하다는 의미이다.

이 중 protected와 private의 경우 항상 사용하는 것이 아니고,

다른 클래스 내에서 중첩된 클래스가 있는 경우 등에 사용하는 것이기에, 일반적으로 많이 사용되는 것은 아니다.

물론 위에 써 놓은건 아주 일반론적인 이야기일뿐, 머 줏어들은 이야기지만,

나중에 실제 복잡한 프로그래밍을 하게 되면, 데이터가 엉키는 것을 방지해

굉장히 많은 변수 등에 접근을 막아 놓게 되는 경우가 있다고 한다.

이건 나중에 상위 레벨로 올라가면서 점차 몸으로 직접 느끼게 되지 않을까 생각한다.

기본적으로 우리가 클래스를 인스턴스 시키고 변수를 선언하고 하면

그것은 특정부분에서만 사용 가능한 지역(local)의 의미만을 가지는데,

static은 그런 local의 범위를 벗어나 다른 곳들에서도 사용 할 수 있다(정적)는 의미로 사용된다.

클래스, 메소드, 변수 등에 모두 선언이 가능한데,

어디에 선언을 하냐에 따라 그 의미가 조금씩 달라지기는 하지만,

적어도 프로그램 전체에 영향을 미친다는 점에서는 같은 의미를 가지고 있다.

보통 일반적인 값들은 인스턴스 되면서 stack이나 heap 영역에 메모리가 생성이 되지만

static은 프로그램의 생성과 동시에 그 값이 선언이 되어,

statck, heap이 아닌 다른 메모리 영역에 할당 된다는 특징이 있다.

이걸 다르게 이야기한다면, 일반적인 클래스 메소드 변수의 경우

main안에서 혹은 특정 클래스 안에서 생성되지 않은 채로 기다리고 있다가

선언을 하는 순간 생성이 되고 다 사용하고 용도가 없어지면 지워진다는 특징이 있다면,

static은 특정 선언의 단계가 없더라도, 프로그램의 생성 시 이미 메모리 상에 상주를 하게 되고,

그렇게 생성된 값들을 이용하기만 하면 된다는 것이다.

static 과 개념은 조금 다르지만, 같이 이야기를 해야 할 녀석으로는 final이란 녀석이 있는데,

final은 값(혹은 내용)을 고정하여 처음에 선언한 그대로만 사용이 가능하여

그 값을 변화시킬 수 없다는 특징이 있다.

일반적으로 static과 콤비로 같이 사용하게 되는 경우가 많아 이렇게 묶어서 이야기 하는것 뿐이다.

final 같은 경우 특정 상황에 대비하여 특정 상황에서 프로그램을 강제 종료시키는 코드를 짤 때

강제 종료시키는 명령값으로 조건을 설정하는데 사용할 수 있는데,

강제 종료시키는 명령값 자체가 프로그램 내에서 변하면 그에 따라 조건이 변해야 하는 문제가 있으므로,

특정하게 값을 고정시켜 그 값을 이용해야 할 경우 사용할 수 있다.

(물론 위의 설명은 변수를 예를 들어 사용한 것이지만, 변수가 아닌 클래스 메소드에도 사용 가능하다)

혹시 몰라 부가적인 설명을 하나 더하자면,

  • final 변수 : 상수 (값을 변경할 수 없음).
  • final 메소드 : 오버라이딩이 안되는 메소드
  • final 클래스 : 상속이 안되는 클래스 정도로 구분하면 될 듯 하다.

final에 관한 내용을 더 이야기하자면 길어질 듯 하니 이건 여기서 그만;

이건 메소드를 실행한 결과 그 메소드에서 최종적으로 특정한 return 값이 없을 경우

return값이 없다라고 선언하는 명령어이다.

프로그램 안에서 메소드를 만든다는 것은 어떤 목적을 가지고 만들게 되는 것일텐데,

그 목적에 따라 return값이 있는 경우도 있고 없는 경우도 있을 것이다.

이게 무슨 의미이냐 하면,

값을 계산하고 그 값을 화면에 출력하고자 하는 계산기 프로그램을 만들고자 할 때,

특정 메소드에서 값을 입력하면 계산만 하게 하는 메소드를 만들 수도 있고

계산까지 하여 계산 된 값을 화면에 출력까지 하게 하는 메소드를 만들 수도 있다.

계산만 하게 하는 메소드를 만든다면

계산만 하는 메소드를 따로 만들고, 출력을 담당하는 메소드를 따로 만들어야 하는데,

계산만 하는 메소드에서 먼저 계산만을 담당하고

출력을 담당하는 메소드에 그 값을 전달하여 화면에 출력을 시켜야 하는데,

계산 메소드 안에서 원하는 모든 프로세스(계산을 하여 출력)가 끝난 것이 아니라

그 값을 이용하여 출력 메소드에서 계산된 값을 사용 하려는 목적인 만큼

계산된 값을 return하여 그 계산된 값을 사용하려는 곳으로 전달하는 과정이 필요하게 되고,

이럴 경우 메소드를 선언할 경우 void 가 아닌 int, double, String 과 같은 다른 타입의 선언이 필요하다.

하지만 계산 메소드를 만들면서 그 안에다가 출력을 담당하는 내용까지 추가를 한다면,

내가 맨 처음 작성하고자 했던 계산 -> 출력의 부분이 해당 메소드 안에 모두 들어가 있게 되므로써

메소드 안에서 계산 된 값이 다른 곳에서 사용 되는 것이 아닌

그 메소드 안에서 원하는 프로세스를 모두 완료시킨 것이 되므로

이럴 경우 return 값이 없으므로 이럴 경우 return 값이 없다라는 것을 알려주고자 void를 사용하게 된다.

출처 : https://blog.naver.com/crazydeicide/130114957734

0%