자바를 이용해 개발하면서 static
이라는 키워드를 많이 봤다.
어떤 식으로 쓰이는지 얼추는 알지만, 어떻게 쓰이고, 언제 쓰이는지 확실하게 알아보자.
static(정적)
: 정적인, 고정된이라는 뜻
사전적 의미 그대로, 변수나 메소드에 static
을 붙이면 클래스에 고정되어 있는 변수나 메소드
가 되며, 이 둘을 정적 멤버
또는 클래스 멤버
라고 한다.
static
키워드를 통해 생성된 정적 멤버들은 Heap영역이 아닌 Static 영역에 할당된다.
장점
: 모든 객체가 공유하여 하나의 멤버를 어디서든지 참조할 수 있다.단점
: Garbage Collector의 관리 영역이 아니기 때문에, Static 영역에 있는 멤버들은 프로그램이 종료될 때까지 메모리가 할당된 채로 존재하게 되어, 멤버가 너무 많은 경우 시스템 성능에 악영향을 줄 수 있다.필드나 메소드를 생성할 때 공용으로 사용하는지 여부에 따라, 인스턴스 또는 정적 멤버로 생성할지 판단하면 된다.
int num = 0; // 타입 필드명 = 초기값
public void defaultMethod(){ ... } // 접근제한자 리턴타입 메소드명()
static int num = 0; // static 타입 필드명 = 초기값
public static void staticMethod(){ ... } // 접근제한자 static 리턴타입 메소드명 {}
이제 자세하게 정적 필드
와 정적 메소드
에 대해서 알아보자.
class Number{
int num1 = 0; // 인스턴스 필드
static int num2 = 0; // 정적 필드
}
public class StaticExam {
public static void main(String[] args) {
// 두 개의 Number 객체(인스턴스) 생성
Number number1 = new Number();
Number number2 = new Number();
// number1 객체(인스턴스)의 두 필드 1 증가
number1.num1++; // 인스턴스 필드
number1.num2++; // 정적 필드
// number2 객체(인스턴스)의 두 필드 출력
System.out.println(number2.num1);
System.out.println(number2.num2);
}
}
결과를 보면 number2
객체의 인스턴스 필드 num1
은 0
으로 증가되지 않았지만, num2
는 1
로 증가된 걸 볼 수 있다.
왜 이런 결과가 나왔냐면, 인스턴스 필드
는 객체(인스턴스)가 생성될 때마다 생성되므로 객체(인스턴스)마다 다른 값을 가지지만, 정적 필드
는 모든 객체(인스턴스)가 하나의 저장공간을 공유해서 항상 같은 값을 가지기 때문이다.
class Name{
// 인스턴스 메소드
void print1() {
System.out.println("인스턴스 메소드 출력");
}
// 정적 메소드
static void print2() {
System.out.println("정적 메소드 출력");
}
}
public class StaticExam {
public static void main(String[] args) {
// 인스턴스 메소드 호출 방법
Name name = new Name(); // 객체(인스턴스) 생성
name.print1(); // 생성한 객체(인스턴스)를 이용해 호출
// 정적 메소드 호출 방법
Name.print2();
}
}
인스턴스 메소드
: 객체(인스턴스)를 생성해 Heap 영역에 올려주고, 생성한 객체(인스턴스)를 통해 호출할 수 있다.정적 메소드
: 클래스가 Static 영역에 올라갈 때 정적 메소드가 자동으로 생성되어, 객체(인스턴스)를 생성하지 않아도 호출이 가능하다.클래스명.정적메소드명
정적 메소드
내에서는 인스턴스 변수
를 사용할 수 없다.
정적 메소드
는 프로그램 실행과 동시에 Static 영역에 올라가지만, 인스턴스 변수
는 객체를 생성해야만 사용이 가능하기 때문에, 객체를 사용하기 전에 먼저 Static 영역에 올라가는 정적 메소드
에서는 사용할 수 없다.