우리가 코드를 짜면서 사용하는 static에 대해 알아보려고 한다. 먼저 메모리 구조에 대해 아는 것이 static을 이해하는 데 도움이 될 것이다. 그러니 메모리 구조를 간략하게 설명하고서 static에 대해 알아보도록 하자!
static의 의미
자바의 메모리 구조에는 Method Area와 Heap Area(그밖에 더 있음)가 존재한다. 각각의 역할을 아래와 같다.
우리가 만든 클래스는 Method Area에 생성되고 new 키워드를 사용해서 만든 객체는 Heap Area에 생성된다.
알다시피 자바에는 Garbage Collector가 메모리를 관리해준다. 하지만 그 관리의 대상은 Heap Area이다. 즉, Method Area는 Garbage Collector의 관리 대상이 아닌 것이다. 그렇다면 무엇이 문제인가?
위에서 알 수 있듯이 Method Area에 static 변수가 보관된다. 그 말은 static 키워드를 사용해서 메모리에 한 번 올라가면 프로그램이 종료될 때까지 메모리를 차지한다는 것이다. 그래서 static을 자주 사용할수록 시스템 퍼포먼스에 악영향을 주게 된다.
static Method 예시
static 변수나 static 메서드는 Method Area에 존재하므로 객체가 생성되기 이전에 이미 할당되어 있기 때문에 객체 생성 없이 바로 접근할 수 있다.
public class StaticMethodEx {
public static void main(String[] args) {
StaticMethodEx2.staticMethod(); // 가능
StaticMethodEx2.notStaticMethod(); // 불가능
StaticMethodEx2 st2 = new StaticMethodEx2();
st2.notStaticMethod(); // 가능
st2.staticMethod(); // 가능하지만 지양해야함.
}
}
class StaticMethodEx2{
static void staticMethod(){
System.out.println("Static 메서드입니다.");
}
void notStaticMethod(){
System.out.println("Static 메서드가 아닙니다.");
}
}
만약에 static 메서드에서 static이 아닌 변수에 접근하면 어떻게 될까??
의외로 간단하게 결론을 도출해낼 수 있다. 당연히 에러가 난다.
public class StaticMethodEx {
public int a = 1; // X
public static int a = 1; // O
public static void main(String[] args) {
Test1();
}
static void Test1(){
System.out.println("a의 값은 " + a + " 입니다.");
}
}
코드만 보면 의문이 생길 수 있지만 그 이유는 간단하다. static 메서드는 이미 메모리에 올라와 있어서 언제든지 접근이 가능한 반면에 a라는 변수는 new 키워드로 객체를 만들어 주지 않으면 메모리에 할당되지 않아서 접근할 수 없다.
그러므로 static 메서드에서 접근하기 위한 변수는 static 변수로 선언되어야 한다.
뿐만 아니라 우리가 자주 사용하는 Math클래스의 내부를 보면 static으로 선언되어 있는 것을 알 수 있다.
public final class Math {
...
public static final double PI = 3.14159265358979323846;
...
public static int max(int a, int b) {
return (a >= b) ? a : b;
}
...
public static int min(int a, int b) {
return (a <= b) ? a : b;
}
...
}
클래스에는 final로 선언되어 상속을 방지하고 static으로 메서드를 선언해서 우리가 Math 클래스의 객체를 생성하지 않아도 메서드에 접근할 수 있다. 이러한 클래스를 유틸리티 클래스라고 한다.
그래서 무작위 숫자를 생성할 때마다 Math.random()로 메서드를 호출해도 우리가 원하는 대로 숫자를 생성해준 것이다.
정리
static 키워드를 사용하면 객체를 생성하지 않아도 바로 접근이 가능!
But, static의 남용은 메모리를 많이 차지하기 때문에 시스템 퍼포먼스에 영향을 끼친다.
그러므로 static의 남용에 주의해서 사용하도록 하자!
▼ 도움을 주신 분들
'Language > Java' 카테고리의 다른 글
[Java] 추상 클래스 VS 인터페이스 (0) | 2022.07.04 |
---|---|
[Java] 오버로딩 VS 오버라이딩 (0) | 2022.06.14 |
[Java]스트림(stream)(3/3) (0) | 2022.06.09 |
[Java]스트림(stream)(2/3) (0) | 2022.06.07 |
[Java]스트림(stream)(1/3) (0) | 2022.06.07 |