이번에는 static에 대해 정리하려고 한다.
우선 static은 정적이라는 의미를 가지고 있다.
static을 활용하여 static변수와 static메소드를 만들 수 있다.
정적변수, 정적메소드라고도 하는데 일반적으로 메소드가 선언되면 지역변수의
데이터 값이 저장되는 공간이 stack 메모리 영역이다.
참조형 데이터 타입을 갖는 객체, 배열 등은 heap 메모리 영역에 쌓인다.
(메모리 영역에 따른 내용은 나중에 따로 다루도록 하겠다.)
그럼 static으로 선언된 변수와 메소드는 어디에 할당이 될까?
static은 static 메모리 영역에 할당이 된다.
static 메모리 영역은 프로그램이 시작될 때부터 종료가 될 때까지 메모리에 남아 있다.
메모리 할당을 한 번만 하기 때문에 메모리 사용에 이점이 있다.
하지만 너무 남발하게 되면 사용하지 않는 변수, 메소드들을 메모리 영역으로 전부 올려버리기
때문에 만들고자 하는 시스템의 성능에 악영향을 줄 수 있다.
static 영역에 할당된 메모리는 모든 객체가 공유하여 하나의 멤버를
어디서든지 참조할 수 있다는 장점을 가진다.
그리하여 멤버 필드나 메소드를 생성 시 인스턴스로 생성할 것인지, 정적으로 생성할 것인지는
공유를 할 것인지 안할 것인지에 대한 기준으로 판단하면 된다.
static 변수
변수 앞에 static이 붙으면 이 변수는 정적 변수가 된다.
static을 사용하는 간단한 예시를 하나 들어보겠다.
static을 사용하지 않는 인스턴스들은 어떻게 값이 변할까?
public class Calculator {
int value = 2;
}
public class staticTest {
public static void main(String[] args) {
Calculator cal = new Calculator();
cal.value++;
System.out.println(cal.value);
}
}
--------------- 출력 결과 --------------------
3
우선적으로 cal이라는 객체를 하나 생성하여 value에 값을 1 더하였다.
그리고 출력을 해보면 3이라는 값이 찍힌다.
여기서 cal2라는 객체를 하나 더 생성하여 값을 출력하면 어떻게 될까?
public class Calculator {
int value = 2;
}
public class staticTest {
public static void main(String[] args) {
Calculator cal = new Calculator();
Calculator cal2 = new Calculator();
cal.value++;
System.out.println(cal.value);
System.out.println(cal2.value);
}
}
-------------- 출력 결과 ------------------
3
2
다른 값이 나오는 것을 확인할 수 있다.
그 이유는 인스턴스를 생성할 때마다 서로 다른 메모리를 가리키고 있기 때문이다.
객체 변수는 항상 독립적인 값을 가진다.
여기서 Calculator의 변수인 value를 static으로 정적 변수로 바꾸면 어떻게 될까?
public class Calculator {
static int value = 2;
}
public class staticTest {
public static void main(String[] args) {
Calculator cal = new Calculator();
Calculator cal2 = new Calculator();
cal.value++;
System.out.println(cal.value);
System.out.println(cal2.value);
}
}
-------------- 출력 결과 ------------
3
3
value이라는 변수가 static 메모리 영역에 올라가 메모리가 할당되어 있기 때문에
새로운 인스턴스를 생성하더라도 같은 메모리를 가리키게 되는 것이다.
static 메소드
메소드 앞에 static이 붙으면 이 메소드는 정적 메소드가 된다.
static을 사용하는 간단한 예시를 하나 들어보겠다.
public class Calculator {
static void staticMethod() {
System.out.println("정적 메소드입니다.");
}
void instanceMethod() {
System.out.println("인스턴스 메소드입니다.");
}
}
public class staticTest {
public static void main(String[] args) {
Calculator.staticMethod(); // 정적 메소드
// 따로 인스턴스를 생성하지 않아도 호출 가능
Calculator cal = new Calculator(); // 인스턴스 메소드
cal.instanceMethod();
}
}
------------------- 출력 결과 -----------------------
정적 메소드입니다.
인스턴스 메소드입니다.
정적 메소드는 클래스가 메모리 영역에 올라갈 때 자동으로 생성이 된다.
그렇기 때문에 따로 인스턴스를 생성하지 않아도 호출이 가능하다.
이런 static은 언제 많이 사용할까?
일반적으로 정적 메소드는 유틸리티 함수를 만드는데에 많이 사용이 된다.
이 예제는 내가 주로 사용하는 시간 처리 함수이다.
public class Utils {
// 시간처리 함수
public static String timeFormat(String dateTime) {
int time = Integer.parseInt(dateTime);
String set_time = "";
if (time < 60) {
set_time = time + "초 전";
} else if (time < 3600) {
set_time = time / 60 + "분 전";
} else if (time < 86400) {
set_time = time / 3600 + "시간 전";
} else if (time < 604800) {
set_time = time / 86400 + "일 전";
} else if (time < 2592000) {
set_time = time / 604800 + "주 전";
} else if (time < 31104000) {
set_time = time / 2592000 + "달 전";
} else {
set_time = time / 31104000 + "년 전";
}
return set_time;
}
}
이처럼 static으로 정적 메소드를 만들어 필요하다면 어디서든
Utils.timeFormat()함수를 통해 참조가 가능하다.
또한 static은 디자인 패턴 중 하나인 싱글톤 패턴을 만들 때 유용하게 사용된다.
(싱글톤 패턴은 나중에 따로 다루도록 하겠다.)
'JAVA' 카테고리의 다른 글
[JAVA] Static Stack Heap 메모리 구조 (0) | 2022.01.06 |
---|---|
[JAVA] Call by value와 Call by reference (0) | 2022.01.06 |
[JAVA] 접근제어자 (0) | 2022.01.04 |
[JAVA] 오버로딩과 오버라이딩 (0) | 2022.01.04 |
[JAVA] 생성자 (0) | 2022.01.04 |