- Today
- Yesterday
- Total
메이쁘
[JAVA] JAVA에서 static(정적) 변수 / 메서드 / 클래스 등 static 키워드란 ? 본문
안녕하세요.
JAVA 를 처음 접하게 되면 볼 수 있는
public static void main(String args[]) {}
여기서 static은 무슨 의미를 갖고 있을까요?
또는
static int a = 10;
여기에서도 사용되는 static은 무슨 의미를 갖고 있을까요?
JAVA에 사용되는 static 키워드에 대해 알아보겠습니다.
static (정적) 의 역할
- 보통 static 은 "정적" 을 뜻합니다. 또한, 변수 / 메소드 / 클래스 앞에 "static" 을 붙여서 사용합니다.
class MainClass {
// static 변수
static int a = 10;
// static 메소드
static int getA() {
return a;
};
// static 클래스 (클래스 내부에 static 클래스를 정의함)
static class InnerStaticClass {}
}
- static 을 클래스에 사용하는 경우는 중첩 클래스(Nested class) 에 사용되므로, 이는 다른 포스트에서 다루겠습니다!
- 이런 방식으로 사용합니다.
일반 변수와 static 변수의 차이
class A {
int a = 10;
static int b = 10;
}
- 이렇게 클래스 내에 멤버 변수(지역 변수) 와 static 변수가 존재한다고 가정합니다. 이 두 변수의 차이는 무엇일까요? 차이를 알기 위해서는 자바 프로그램이 실행하는 과정을 대략적이라도 알아야 합니다. (별도 포스트에서 다루겠습니다.)
설명드리자면, Java는 JVM을 통해 Java 코드를 OS 환경 위에서 실행할 수 있습니다. 이 때, Runtime Data Area (보통 런타임이라고 부릅니다.) 안에 Method Area(Static Area), Heap Area 가 포함되어있죠.
*** 이는 메모리 영역입니다.
여기서, 멤버 변수(클래스 내 지역변수) 는 인스턴스 생성 시(new 키워드를 통한 객체 생성 / 할당) 인스턴스와 함께 Heap 영역 안에 메모리를 할당받습니다. 이 멤버 변수는 인스턴스 메모리 내에 함께 할당받아있죠.
즉, 인스턴스 생성 시 Heap 영역에 메모리를 할당받게 되며, 인스턴스에 접근해야지 해당 멤버 변수를 사용할 수 있습니다.
반면, static 변수는 멤버 변수와는 다르게 Method Area(Static Area) 에서 메모리를 할당받습니다. 또한, static 키워드는 프로그램 실행 시 JVM에서 미리 Method Area에 메모리를 할당받아놓습니다.
그렇기 때문에, static 변수는 프로그램 실행 시 메모리 할당 /// 프로그램 종료 시 메모리 삭제 가 이루어집니다.
*** 이러한 이유로 static 키워드를 많이 사용하게 되면 메모리 초과, 속도 저하 등 문제가 발생할 수 있기에 적당히 사용해야 합니다.
*** Method Area(Static Area) 에는 클래스, static 키워드 들이 메모리를 할당받음. (정적 할당)
*** Heap Area 에는 객체(인스턴스) 들이 메모리를 할당받음. (동적 할당)
그래서 만약 객체를 n개 생성한다면, 멤버 변수 또한 Heap 영역의 객체 메모리 내부에 n개를 할당받게 되죠.
하지만, static 변수는 프로그램 실행 시 단 1개만 Method 영역에 메모리를 할당받습니다.
이해되셨나요?
그 결과로, 메모리 할당 영역 및 할당 시간의 차이가 있기 때문에 각각의 변수에 대한 접근 방식이 다릅니다.
접근 방법
class A {
int a = 10;
static int b = 20;
}
class MainClass {
public static void main(String args[]) {
A tempA = new A();
System.out.println(A.a); // 인스턴스 생성 없이 멤버 변수 직접 접근 불가능.
System.out.println(A.b); // static 변수이기 때문에 인스턴스 생성 없이 직접 접근 가능함.
System.out.println(tempA.a); // 가능
System.out.println(tempA.b); // 가능하지만 권장하지 않음.
}
}
- static 변수는 별도의 인스턴스 생성 없이 클래스 이름으로 직접 접근할 수 있습니다.
- 또한, 인스턴스에서 호출은 가능합니다만 굳이 권장하지 않습니다. 그 이유는 말안해도 아시겠죠?
다른 하나의 예시 코드를 보여드리겠습니다.
class MainClass {
int a = 10;
static int b = 20;
// static -> non-static 호출 : 불가능(X)
static int getNumber() {
return a;
}
// static -> static 호출 : 가능(O)
static int getNumber() {
return b;
}
// non-static -> non-static 호출 : 가능(O)
int getNumber() {
return this.a;
}
// non-static -> static 호출 : 가능(O)
int getNumber() {
return b; // this는 불가능
}
}
- this는 현재 객체를 가리킵니다. 그렇기 때문에, 프로그램 실행 시 메모리를 할당받은 static 변수에는 this를 사용할 수 없습니다.
- static 메소드 내에서 non-static(멤버 변수) 사용은 불가능합니다. 그 이유는 위에서 말햇듯이 프로그램 실행 시 메모리에 할당되는데, 실행할 때 멤버 변수 a 는 메모리에 할당되어 있지 않기 때문에 참조할 수가 없는 것이죠.
활용 방안
- 정말 무수히 많지만, 대표적으로 몇개 꼽자면
-> 전역 변수
-> Util 클래스(예를 들어, 문자열을 포맷하는 함수, 날짜 출력하는 함수 등)
-> Singleton 패턴 (디자인 패턴 중 하나. 단 하나의 인스턴스로 설계하는 방식)
가 있습니다.
궁금한 점, 틀린 곳이 있다면 댓글 부탁드립니다.
감사합니다!
'Language > JAVA' 카테고리의 다른 글
[Java] ThreadLocal 정의 및 기본 사용법 - Tutorial(Sample) (1) | 2021.12.09 |
---|---|
[Java] Java란 무엇일까? Java는 어떻게 동작되고 컴퓨터에서 실행되는 걸까? (0) | 2020.09.06 |
[JAVA] Integer.parseInt() 와 Integer.valueOf() 의 차이점 간단 설명! (0) | 2020.05.31 |
[JAVA] String, StringBuilder, StringBuffer 의 차이점 (0) | 2020.04.06 |
[JAVA] java.lang.IllegalArgumentException: Comparison method violates its general contract! 에러 해결 (4) | 2020.04.05 |