- static
- 클래스의 멤버(필드, 메서드, 이너 클래스)에 사용하는 제어자
- 인스턴스 멤버(instance member)
- 객체 안에 있을 때 상요할 수 있는 상태가 되는 멤버
- 정적 멤버(static member)
- static이 붙어 있는 멤버
- 객체의 생성 없이 '클래스명.멤버명'만으로 바로 사용 가능
1. 인스턴스 필드와 정적 필드
class A {
int m = 3; //객체를 생성한 후 사용 가능
static int n =5; //객체 생성 없이 사용 가능
}
- 인스턴스 필드와 정적 필드의 메모리 구조
- 인스턴스 필드의 활용 방법 - 객체를 생성한 후에 사용 가능
A a = new A();
System.out.println(a.m); //3
- '참조 변수명. 인스턴스 필드명'
- 인스턴스 필드인 m의 저장공간은 객체 내부에 생성되므로 m을 사용하기 위해서는 반드시 객체를 먼저 생성
- 저장공간이 힙 메모리에 위치하므로 반드시 해당 저장 공간에 값을 읽거나 쓰기 위해서는 참조 변수명 사용
- static 필드의 활용 방법 1 - 객체를 생성하지 않고 바로 사용
System.out.println(A.n); //5
- '클래스명.정적 필드명'
- 정적 필드인 n은 클래스 내부에 저장 공간을 지니고 있기 떄문에 객체 생성 없이 바로 사용 가능
- static 필드의 활용 방법 2 - 객체를 생성한 후 사용(권장 x)
A a = new A();
System.out.println(a.n); //5
- 객체 내부에 정적 필드인 n도 존재
- n의 실제 저장 공간 = 정적(static)영역
n의 저장공간의 참좃값 = 객체 내부 영역
- 인스턴스 필드 처럼 참조 변수명으로도 사용 가능
- 정적필드는 객체 간 공유 변수의 성질이 있다.
- 정적 필드의 공유 특성 예
A a1 = new A();
A a2 = new A();
a1.m =5; //a1 객체의 인스턴스 필드 m에 값 5 입력
a2.m =6; //a1 객체의 인스턴스 필드 m에 값 6 입력
System.out.println(a1.m); //5
System.out.println(a2.m); //6
a1.n = 7; //a1 객체의 정적 필드 n에 값 7 입력
a2.n = 8; //a1 객체의 정적 필드 n에 값 8 입력
System.out.println(a1.n); //8
System.out.println(a2.n); //8
A.n = 9;
System.out.println(a1.n); //9
System.out.println(a2.n); //9
- 객체 a1, a2를 생성하면 힙 메모리에 2개의 객체가 만들어짐
- 인스턴스 필드 m은 객체안에 실제 데이터 값 저장
- 정적 필드 n은 정적(클래스)영역의 클래스 A안에 실제데이터값 저장
객체 안에는 실제데이터값의 위칫값을 저장
- a1 객체의 정적 필드 n과 a2 객체의 정적 필드 n은 모두 클래스 A에 저장된 값을 똑같이 가리키고 있음
-a1.n = 7 입력시 n이 가리키는 곳에 7을 저장
-a2.n = 8 입력시 n이 가리키는 곳에 8dmf wjwkd
-두 정적 필드 n이 가리키는 곳이 같으므로 기존에 저장돼 있던 값 7이 지워지고 8이 저장
- 정적필드가 사용되는 예
- 은행통장 클래스로 열 사람의 은행통장 객체를 생성
- 이자필드 = 정적 필드
- 금리가 바뀌어 '은행통장.클래스.이자'를 바꾸면 모든 은행통장 객체들이 모두 이 값을 적용받게 됨
2. 인스턴스 메서드와 정적 메서드
- 인스턴스 메서드 : 반드시 객체를 생성한 후에 사용
- 정적 메서드 : 클래스명으로 바로 접근 가능
class A {
void abc() {
System.out.println("instance 메서드");
}
static void bcd() {
System.out.println("static 메서드");
}
}
//인스턴스 메서드의 활용 방법
A a = new A(); //객체를 생성한 후에 사용 가능
a.abc();
//정적 메서드의 활용 방법
A.bcd();
- 인스턴스 메서드와 정적 메서드는 모두 메모리의 첫 번째 영역에 위치
- 인스턴스 메서드는 인스턴스 메서드 영역, 정적 메서드는 클래스 내부에 존재
- 인스턴스 메서드와 정적 메서드의 메모리 구조
3. 정적 메서드 안에서 사용할 수 있는 필드와 메서드
- 정적 메서드 내에서는 정적 필드 또는 정적 메서드만 사용 가능
- 인스턴스 메서드 내에서는 인스턴스 멤버와 정적 멤버 모두 사용 가능
- 정적 멤버 ( 정적 필드, 정적 메서드)는 객체의 생성 없이 실행될 수 있어야 함
- But, 인스턴스 멤버(인스턴스 필드, 인스턴스 메서드)는 반드시 객체를 생성한 후에 사용 가능
- 객체 생성 이전에 실행하려면 내부에는 객체 생성 이전에 사용할 수 있는 요소들로만 구성돼 있어야 함
- 정적 메서드 내부에서는 클래스 내부에서 자신의 객체를 가리키는 this 키워드를 사용할 수 없음
- this.가 자동으로 붙어야 하는 인스턴스 멤버는 올 수 없음
class A {
int a;
static int b;
void abc() {
//a,b, bcd(), cde() 사용 가능
}
static void bcd() {
//b,cde() 사용 가능
}
static void cde() {
//b, bcd() 사용 가능
}
}
4. 정적 초기화 블록
- 인스턴스 필드의 초기화는 객체가 만들어지는 시점에서 이뤄짐. 즉, 객체가 생성자에서 만들어지므로 생성자 내에서 인스턴스 필드를 초기화
- 정적 필드는 객체의 생성 이전에도 사용할 수 있어야 하므로 생성자가 호출되지 않은 상태에서도 초기화할 수 있어야 함
- 생성자에서는 정적 필드를 초기화 할 수 없음
- 정적 초기화 블록(static {})사용
static {
//클래스가 메모리에 로딩될 떄 실행되는 내용
}
- 정적 초기화 블록은 클래스가 메모리에 로딩될 때 가장 먼저 실행
- 여기에 정적 필드의 초기화 코드를 넣어 두면 클래스가 로딩되는 시점에 바로 추가
package StaticInitialBlock;
class A {
int a;
static int b;
static {
b=5; //정적 필드의 초기화는 static{}내에서 수행
System.out.println("클래스 A가 로딩됐습니다!");
}
A() {
a=3; //인스턴스 필드 초기화는 일반적으로 생성자에서 수행
}
}
public class StaticInitialBlock {
public static void main(String[] args) {
System.out.println(A.b); //A.b가 실행되는 시점에 클래스 A가 메모리에 로딩되며, 이때 static{} 초기화 블록 실행
}
}
5. static main() 메서드
- public static void main(String[] ar)도 정적 메서드
- 자바 가상 머신은 프로그램을 실행할 때 '실행 클래스명.main()'을 실행하므로 가장 먼저 실행되는 메서드인 main()메서드를 정적 메서드로 구현
'Java > 문법' 카테고리의 다른 글
10-2장 객체의 타입 변환 (0) | 2023.05.04 |
---|---|
10-1장 클래스 상속의 개념과 문법적 특징 (0) | 2023.05.04 |
9-1장 접근 지정자 (0) | 2023.04.30 |
8-2 장 외부 클래스 (0) | 2023.04.24 |
8-1장 패키지와 임포트 (0) | 2023.04.24 |