static 키워드
- static은 클래스의 멤버(필드, 메서드, 이너 클래스)에 사용하는 키워드
- static 키워드가 붙은 멤버를 '정적 멤버'라고 부르며, 인스턴스 생성 없이 '클래스명.멤버명'만으로 사용할 수 있다.
- 정적 멤버는 인스턴스를 생성한 후 참조 변수를 통해 사용할 수도 있지만, 정적 멤버임을 나타내기 위해 권장 x
정적 필드
- 메모리가 독립되어 있다.
-> 정적 필드는 클래스 내부에 저장 공간을 지니며, 인스턴스 내부에는 실제 정적 필드의 저장 공간의 주소값만 포함하고 있다. - 정적 필드는 객체 간 공유 변수의 성질을 가지고 있다.
- 이러한 특징으로 정적 필드를 클래스별로 관리하는 '클래스 필드'라고 한다.
public class Main {
public static void main(String[] args) {
MyClass mc1 = new MyClass();
MyClass mc2 = new MyClass();
mc1.instanceField += 100; // mc1 참조 변수를 통해 인스턴스 필드 + 100
System.out.println("mc1.instanceField : " + mc1.instanceField); // mc1은 증가
System.out.println("mc2.instanceField : " + mc2.instanceField); // mc2는 변화 x
MyClass.staticField += 100; // 정적 필드 + 100
System.out.println("mc1.staticField : " + mc1.staticField); // 객체 간 공유
System.out.println("mc2.staticField : " + mc2.staticField); // 객체 간 공유
}
}
class MyClass {
int instanceField = 100; // 인스턴스 필드
static int staticField = 100; // 정적 필드
}
정적 메서드
- 정적 메서드는 메모리상 클래스 내부에 존재한다.
인스턴스 메서드는 메모리상 인스턴스 메서드 영역에 존재함. - 정적 메서드 내부에는 정적 멤버만 올 수 있다.
-> 인스턴스 생성없이 호출할 수 있어야 하기 때문에
public class Main {
public static void main(String[] args) {
MyClass mc1 = new MyClass();
MyClass mc2 = new MyClass();
mc1.instanceMethod(100);
System.out.println("mc1.instanceField : " + mc1.instanceField);
System.out.println("mc2.instanceField : " + mc2.instanceField);
MyClass.staticMethod(100); // instanceMethod에서 더한 값이 공유 (200 + 100)
System.out.println("mc1.staticField : " + mc1.staticField);
System.out.println("mc2.staticField : " + mc2.staticField);
}
}
class MyClass {
int instanceField = 100; // 인스턴스 필드
static int staticField = 100; // 정적 필드
void instanceMethod(int num) { // 인스턴스 메서드
instanceField += num;
staticField += num;
}
static void staticMethod(int num) { // 정적 메서드
// instanceField += num; -> 정적 멤버가 아니기 때문에 불가능
staticField += num;
}
}
정적 필드 초기화 - 정적 블록
정적 필드는 객체의 생성 이전에도 사용할 수 있어야 하므로 생성자가 호출되지 않은 상태에서도 초기화할 수 있어야 한다.
정적 블록(static block)을 통해 정적 필드를 초기화할 수 있다.
정적 초기화 블록은 클래스가 메모리에 로딩될 때 제일 먼저 실행된다.
// 정적 초기화 블록
static {
// 클래스가 메모리에 로딩될 때 실행할 내용
}
// 예시
public class Main {
public static void main(String[] args) {
MyClass mc1 = new MyClass(100);
MyClass mc2 = new MyClass(100);
mc1.instanceMethod(100);
System.out.println("mc1.instanceField : " + mc1.instanceField);
System.out.println("mc2.instanceField : " + mc2.instanceField);
MyClass.staticMethod(100); // instanceMethod에서 더한 값이 공유 (200 + 100)
System.out.println("mc1.staticField : " + mc1.staticField);
System.out.println("mc2.staticField : " + mc2.staticField);
}
}
class MyClass {
int instanceField; // 인스턴스 필드
static int staticField; // 정적 필드
public MyClass(int num) { // 생성자를 통해 인스턴스 필드 초기화
instanceField = num;
}
static { // 정적 블록
System.out.println("정적 블록이 실행되었습니다.");
staticField = 100; // 정적 초기화 블록으로 정적 필드 초기화
}
void instanceMethod(int num) { // 인스턴스 메서드
instanceField += num;
staticField += num;
}
static void staticMethod(int num) { // 정적 메서드
staticField += num;
}
}
'Langauge > Java-basic' 카테고리의 다른 글
[Java] 상속 관계와 포함 관계 (0) | 2022.07.29 |
---|---|
[Java] final 키워드 (0) | 2022.07.25 |
[Java] 접근 제어자 public / protected / default / private (0) | 2022.07.23 |
[Java] 이너 클래스 (0) | 2022.07.22 |
[Java] 외부 클래스 (0) | 2022.07.21 |