클래스는 객체(인스턴스)를 만들기 위한 '설계도' 역할을 하고, 인스턴스는 실제로 메모리에 할당된 객체를 의미한다.
static
키워드로 정의된다)static
static
은 고정된(정적인)이라는 의미를 가지고 있으며, 자바에서 static
키워드를 통해 정적 변수(클래스 변수)와 정적 메서드(클래스 메서드)를 정의할 수 있다. 이를 정적 멤버 또는 클래스 멤버라고 한다.
static
멤버의 메모리 할당static
으로 선언된 멤버는 Heap 영역이 아닌 Method 영역(Static 영역)에 할당된다. Static 영역에 있는 변수는 프로그램이 종료될 때까지 메모리에 유지되며, 모든 인스턴스에서 접근이 가능하다. 하지만, Static 변수는 메모리가 프로그램 종료 시까지 유지되므로 과도하게 사용하면 메모리 관리에 부정적인 영향을 줄 수 있다.
class Number {
static int num = 0; // 클래스 필드
int num2 = 0; // 인스턴스 필드
}
public class StaticEx {
public static void main(String[] args) {
Number number1 = new Number();
Number number2 = new Number();
number1.num++; // 클래스 필드를 1 증가시킴
number1.num2++; // 인스턴스 필드를 1 증가시킴
System.out.println(number2.num); // 1 (공유된 클래스 필드)
System.out.println(number2.num2); // 0 (독립적인 인스턴스 필드)
}
}
여기서 number1
과 number2
는 동일한 num
이라는 클래스 필드를 공유하기 때문에 num
은 1로 출력된다. 반면에 num2
는 각 객체마다 독립적이므로, number2.num2
는 여전히 0을 유지한다.
정적 메서드는 인스턴스와 무관하게 동작하므로, 클래스 이름으로 직접 호출할 수 있다. 정적 메서드에서는 인스턴스 필드나 인스턴스 메서드를 참조할 수 없다.
class Name {
static void print() {
System.out.println("홍길동");
}
void print2() {
System.out.println("이순신");
}
}
public class StaticEx {
public static void main(String[] args) {
Name.print(); // 클래스 메서드는 인스턴스 없이 호출 가능
Name name = new Name();
name.print2(); // 인스턴스 메서드는 인스턴스 생성 후 호출 가능
}
}
Name.print()
는 정적 메서드이기 때문에 인스턴스 없이 호출 가능하지만, name.print2()
는 인스턴스를 통해서만 호출할 수 있다.
클래스 변수와 메서드는 공유 자원에 적합하다. 여러 인스턴스가 같은 값을 유지하거나 관리할 필요가 있을 때 클래스 변수를 사용하면 효율적이다. 하지만 정적 멤버는 인스턴스 멤버에 접근할 수 없다는 규칙을 기억해야 한다. 이는 클래스가 먼저 로딩되고, 인스턴스는 나중에 생성되므로 인스턴스 멤버가 존재하지 않을 수 있기 때문이다.
class Variable {
String instanceVariable;
static String classVariable;
// 인스턴스 메서드
void doFunc1() {
System.out.println("doFunc1() 호출 : " + this.instanceVariable);
}
// 클래스 메서드
static void doFunc2() {
System.out.println("doFunc2() 호출 : " + classVariable);
// System.out.println("doFunc2() 호출 : " + this.instanceVariable); // 오류 발생
}
}
public class VariableEx02 {
public static void main(String[] args) {
Variable v1 = new Variable();
Variable v2 = new Variable();
v1.instanceVariable = "홍길동";
v2.instanceVariable = "강감찬";
v1.doFunc1();
v2.doFunc1();
Variable.doFunc2(); // 클래스 메서드는 인스턴스 없이 호출
}
}
doFunc1()
은 인스턴스 메서드이므로 this
키워드를 사용해 인스턴스 변수를 참조할 수 있지만, doFunc2()
는 클래스 메서드이기 때문에 this
나 인스턴스 변수에 접근할 수 없다.
- 인스턴스 필드/메서드는 각각의 객체에 속하며 독립적으로 관리된다.
- 클래스 필드/메서드는 모든 객체가 공유하는 자원이다.
static
키워드로 선언된 멤버들은 프로그램이 종료될 때까지 메모리에 유지되며, 인스턴스 없이도 클래스 이름으로 호출할 수 있다.- 클래스 메서드는 인스턴스 필드에 접근할 수 없으며, 인스턴스와 무관한 로직을 처리하는 데 사용된다.