static이란
static은 메서드 영역에 저장할 것을 지정하는 키워드이다. static을 사용하는 이유는 1)특정 클래스의 인스턴스들이 공통으로 사용할 것을 공유 2)인스턴스 생성 없이 특정 기능 사용을 위함이다.
클래스 맴버변수(클래스명.클래스 맴버변수)
- static 키워드가 있는 맴버변수.
- 프로그램 전 범위에서 공유된다.
- 인스턴스 없이도 사용이 가능하다. 그 이유는 이미 JVM의 메서드 영역에 올라와 있기 때문이다.
- 중복된 이름은 사용가능하다. 그 이유는 클래스 맴버변수는 클래스 소속이라 클래스마다 별도에 static 영역을 가지기 때문이다.
클래스 메서드(클래스명.클래스 메서드)
- static 키워드가 있는 메서드.
- 프로그램 전 범위에서 공유된다.
- 인스턴스 생성 없이 호출 가능. (이유는 static 변수와 동일)
- 중복된 이름은 사용가능하다
- staitc 메서드나 static 변수만 사용할 수 있다. 그 이유는 인스턴스 변수와 인스턴스 메서드는 힙 영역에 있지만 static 영역은 메서드 area에 존재하기 때문이다. 따라서 서로 접근이 불가하다.
인스턴스 맴버변수
static 키워드가 없는 맴버변수. 인스턴스 생성을 해야 사용가능
// 같은 static이라 객체 생성 x
package fc.java.model;
public class MyUtil {
public static int hap(int a, int b){
int sum = a + b;
return sum;
}
}
**// staticAccess**
package fc.java.part3;
import fc.java.model.*;
public class StaticAccess {
public static void main(String[] args){
int a = 10;
int b = 30;
int sum = MyUtil.hap(a,b); // 클래스 이름.호출 메서드
System.out.println(sum);
}
}
static 활용하기
public class QMember extends EntityPathBase<Member> {
private static final long serialVersionUID = -849062639L;
public static final QMember member = new QMember("member");
public final StringPath username = createString("username");
public final NumberPath<Long> id = createNumber("id", Long.class);
}
프로그램 전 범위에서 공통으로 사용할 변수나 메서드에 static을 지정한다. ex1) QueryDsl에서 Qentity 생성 시 생성자에 static이 붙는다. 그 이유는 생성자에 static이 없다면 매번 QMember member = new QMember("member"); 를 해주어야한다. 따라서 static 키워드를 넣음으로써 우리는 아래와 같이 코드를 작성하는 것이 가능하다.
queryFactory.select(member.username)
.from(member)
.fetch();
ex2) 이메일 검증이 필요한 부분에서 EMAIL_PATTERN 생성 없이 사용이 가능하다.
public static final Pattern EMAIL_PATTERN = Pattern.compile("^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}$");
static과 메모리의 관계
메인 클래스가 new없이 실행되는 이유: static 키워드가 있어서다.
main 클래스의 실행방식
- JVM이 실행할 클래스를 찾는다.
- 찾았을 시 Method area의 static zone으로 보냄(static 키워드가 있는 맴버들은 static zone에 딱 한번 자동으로 로딩)
- JVM이 static zone에 있는 main() 메서드를 호출
- 호출된 메서드를 **Call Stack Area(Stack Area OR Call Stack)**에 push(기계어 코드를 넣고) 한 뒤 동작 시작(실행)
즉 static 키워드가 있으면 1) static zone으로 보낸다. 2) static zone에서 stack area로 호출됨 3) stack area에서 실행
- 용어PC(Program Counter): Call Stack Frame Area에 있는 것으로 현재 실행 중인 프로그램을 가리킴(point 함)
- Frame: 지역(지역 변수 할 때 그 지역)
- 프로그램 종료: Call Stack Frame Area에 프로그램이 없는 상태
- Call Stack Frame Area(Stack Area OR Call Stack): 메서드가 호출되면 호출된 기계어코드가 push되며, 실행되는 메모리 공간이다. 1) PC를 통해 현재 프로그램의 실행 상태를 파악할 수 있다. 2) LIFO(Last-In-First-Out) 구조이다-동전 저장기-
**// static**
package fc.java.part3;
public class StaticTest {
public static void main(String[] args){
int a = 10;
int b = 20;
int sum = hap(a,b);
System.out.println(sum);
}
public static int hap(int a, int b) {
int sum = a + b;
return sum;
}
}
static과 none static의 맴버들의 접근 방법
none static에 접근하려면 객체를 생성해야 한다.
main 클래스의 실행방식 + none static 있는경우
- JVM이 실행할 클래스를 찾는다.
- 찾았을 시 Method area의 static zone으로 보냄(static 키워드가 있는 맴버들은 static zone에 딱 한번 자동으로 로딩)
- JVM이 static zone에 있는 main()메서드를 호출
- 호출된 메서드를 **Call Stack Frame(지역) Area(Stack Area OR Call Stack)**에 push(기계어 코드를 넣고) 한 뒤 동작 시작(실행)
- none static 시작: main 클래스의 인스턴스(NoneStaticTest st;) 생성(인스턴스는 Heap Area에 로딩)
- 인스턴스의 메서드(st.hap)가 호출되면 Heap Area에 있는 인스턴스 메서드(st.hap)의 주소 값을 따라감
- 메서드(st.hap)의 원래 위치인 Method Area의 none static zone(hap이 로딩되어 있는 곳)에 도착
- 호출된 메서드(st.hap)를 **Call Stack Frame(지역) Area(Stack Area OR Call Stack)**에 push(기계어 코드를 넣고) 한 뒤 동작 시작(실행)
- Heap Area: 객체가 생성(new)되는 메모리 공간
- Method Area: 1) 메서드의 기계어 코드가 할당되는 메모리 공간 2) static 맴버들이 할당되는 메모리 공간 3) static zone과 none static zone으로 구분되어 있음
**// none static**
package fc.java.part3;
public class NoneStaticTest {
public static void main(String[] args) {
int a = 10;
int b = 20;
NoneStaticTest st = new NoneStaticTest(); //객체 생성 및 Heap Area 로딩
int sum = st.hap(a,b);
System.out.println(sum);
}
public int hap(int a, int b){
int v = a+b;
return v;
}
}
객체 생성과 static과의 관계
- 클래스의 맴버가 전부 static 맴버면 객체생성 안해도 된다. 왜냐하면 ****Method Area의 static zone에 static이 붙은 맴버들은 이미 로딩되어 있기 때문이다.
- 전부 static일 때 생성자 메소드를 private으로 만들어 객체를 생성하지 못하게 하는 경우도 있다 ex) System, Math → System.out.println(); Math.min(); 따라서 생성자는 반드시 public이다는 틀린 말.
Class, Object, Instance 구분하기
class: 새로운 자료형으로 현실세계의 객체를 설계하는 도구, 설계도에 해당
Object: 클래스를 통해 선언되는 변수로 구체적인 실체 가리킴 X(객체변수) 즉 공간만 존재 ex) Student st;
instance: 객체생성에 의해 메모리에 만들어진 객체로 구체적 실체를 가리키는 상태(인스턴스 변수). 실체가 있으며 공간 안에 틀이 있는 상태 ex) Student st = new Student();
🔗레퍼런스
참고 강의/글
- 인프런 김영한의 자바 기본편
- 자바의 정석
- 페스트켐퍼스 시그니처 백엔드. [course 1]
'Java' 카테고리의 다른 글
| 30. final 키워드 (0) | 2025.08.27 |
|---|---|
| 28. 접근 제어자 (1) | 2025.07.28 |
| 27. 생성자 (1) | 2025.07.25 |
| 26. 절차지향 VS 객체지향 (1) | 2025.07.24 |
| 25. 기본형과 참조형, 변수와 초기화 그리고 null (0) | 2025.06.24 |