Java

[Java]전역변수와 지역변수 & modifier

MoZZANG 2022. 3. 7. 20:30

멤버변수(클래스안에서 선언된 변수)는 해당 클래스안의 모든 메서드에서 사용 가능하고 전역변수(Global variable)와 같다. 멤버변수는 초기화를 하지 않고 사용해도 해당 자료형의 기본값으로 초기화 된다.
예] int : 0, double : 0.0 참조형 : null, boolean : false 등

지역변수(Local Variable)는 특정 지역 안에서 선언되어 그 지역에서만 사용되는 변수로 그 지역을 벗어나면 그 변수는 메모리에서 사라진다.

메소드 안에서 선언된 변수 혹은 Block(if문,while문,for문,try문등) ({ })안에서 선언된 변수를 지역변수라 한다. 
또한 매개변수도 지역변수이다. 지역변수는 선언된 곳을 벗어나면 메모리가 해제된다.
지역변수는 사용시 반드시 초기화를 하고 사용해야 한다.
즉, 지역변수는 자동으로 초기화가 안된다.

※지역변수 앞에는 modifier(지정자)중 (final/abstract/static)중 final만 붙일 수 있다. 하지만 거의 안쓴다.

abstract는 클래스와 메소드앞에만 붙일 수 있으며 static는 못붙인다.

 

또한 지역변수 앞에는 접근지정자를 사용할 수 없다.

 




이제 예제를 보면서 좀 더 알아보자

▲ 맴버변수 앞에는 모든 접근지정자를 사용할 수 있다. 또한 맴버변수는 초기화를 하지 않아도 자동초기화가 된다.

두번째와 세번째 코드는 모드 package접근지정자가 생략되어 있는 것이다.

 

 

▲ 11행에서의 sum은 맴버변수가 아니라 getTotal이라는 메소드의 지역변수이므로 자동초기화가 안된다. 따라서 12행에서 sum을 출력할 수 없다고 error가 날 것이다. 

 

19행에서 변수 i는 for문 block안에서만 사용할 수 있는 지역변수이기 때문에 for문이 종료되면 메모리가 삭제되기 때문에 for문 바깥에서 사용할 수 없다. 

 

sum, start, end도 역시 getTotal메소드의 지역변수이기 때문에 getTotal 메소드를 벗어나서는 사용할 수 없다.

 

 

▲ 23행의 strResult 역시 if문의 지역변수이므로 자동초기화가 되지 않는다. 따라서 초기화전에 24행처럼 출력할 수 없다. 값이 없기 때문이다.

 

30행에서 strResult를 "총합은 홀수"로 초기화하려고 해도 위 코드에서 strResult는 if문안에서 선언된 지역변수이므로 if문을 벗어나서는 사용불가하며 만약 그래도 사용하고 싶다면 else문안에서 다시 변수선언 및 초기화를 하던지, if문 위에서 변수를 선언하면 else문에서도 사용할 수 있다.

 

32행의 mNoInit의 출력값은 0일 것이다. 최초에 맴버변수로 선언만 했고 초기화는 안했기 때문에 int형으로 자동 초기화 되었기 때문이다.

 

 

 

 

 

이제 main메소드에서 결과들을 호출해볼건데 그 전에 modifier에 대해서 알아야한다.

 

- 멤버변수는 크게 정적멤버 변수와 인스턴스형 멤버변수로 나눈다.
- 멤버메소드도 정적메소드 와 인스턴스형 메소드로 나눈다.
- 멤버변수나 멤버 메소드 앞에 static이라는 modifier가 붙으면 정적 멤버 즉 정적 멤버변수이거나 정적 메소드이다.

 

클래스의 맴버에 static이 붙으면 정적맴버 붙지않으면 인스턴스형 맴버이다.

 

인스턴스형 맴버변수는 반드시 클래스를 인스턴스화(객체화, heap영역에 메모리생성)하여 인스턴스 변수로 접근해야 한다.

 

정적 맴버변수는 인스턴스화 할 필요없이 클래스명으로 접근하면된다. 왜냐하면 JVM에서 클래스를 로드할 때 메모리가 이미 생성되기 때문이다.

 

아래의 그림을 보자.

Java.class파일이 읽힐 때 JVM을 거치는데 static이 붙은 정적맴버변수는 Class Lorder단계에서 메모리가 생성되지만 static이 붙지않은 인스턴스형 변수들은 마지막 단계인 interpreter단계에서 메모리가 생성된다. 

 

 

 

자 이제 다시 위쪽에서 만든 맴버변수와 맴버메소드들을 main메소드에서 출력하러 가보자.

▲ 36행에서 맴버변수인 mNoInit이 error가 나는 이유는 위에서 본JVM에서 순서가 맞지 않아서 이다. 즉, 인스턴스형 변수이기 때문이다. main메소드는 static이 붙은 정적메소드이기 때문에 JVM에서 Class Lorder단계에서 static이 붙은녀석들의 메모리를 먼저 만들 때 인스턴스형 변수인 mNoInit은 아직 메모리가 생성되지 않았기 때문이다. 인스턴스형 변수는 마지막 단계인 interpreter단계에서 만들어지기 때문이다.

 

이럴 때는 1. 해당 인스턴스형 맴버도 static을 붙여서 정적맴버로 만드는 방법과

              2. 클래스객체를 생성해서 접근하는 방법이 있다. new를 이용해 객체를 만드는 순간 바로 메모리가 생성되기  때문이다. 

 

38행에서처럼 객체화를 시켜주어야하는 것이다.

 

이후에는 tistory형 메모리의 이름인 tis를 이용해서 상속받은 tistory클래스의 맴버들을 사용할 수 있게 되는 것이다.

 

물론 mNoInit은 같은 클래스 안이기 때문에 사용할 수 있는 것이지 다른 클래스에서는 private이기 때문에 호출 할 수 없다.

 

 

***배열은 지역에서 선언된 배열이든 클래스의 맴버로 선언된 배열이든 해당자료형으로 자동초기화가 된다***

 

'Java' 카테고리의 다른 글

[Java]Static block  (0) 2022.03.07
[Java]modifier part.2  (0) 2022.03.07
[Java]접근지정자(Access Modifier)  (0) 2022.03.07
[Java]Class - part.3  (0) 2022.03.05
[Java]Class - part.2  (0) 2022.03.04