-
[JAVA] Static 키워드자바 2024. 8. 20. 10:41
[JAVA] Static 키워드
코드를 짜면서 static이라는 키워드에 대해 생각을 하지 않았다 면접 준비할 때 static이 뭔지에 대해서 암기만 했을 뿐... 이번에 왜 메서드와 클래스에 static을 넣었냐는 질문을 받으니 그냥...이라
gitofjy.tistory.com
면접을 위해 단순 암기 했던 static 키워드
그리고 면접 때 제대로 된 답변을 못해 한 번 더 공부 후 정리했었다.
1년이 지난 지금 실무를 하고 다시 공부를 해보니 더욱 정리가 되는 느낌이다.
정말 마지막 정리 !
자바 메모리 구조
1) 메서드 영역(Method Area)
- 메서드 영역은 프로그램을 실행하는데 필요한 공통 데이터를 관리한다. 이 영역은 프로그램의 모든 영역에서 공유한다. 1. 클래스 정보 : 클래스의 실행 코드(바이트 코드), 필드, 메서드와 생성자 코드 등 모든 실행 코드가 존재한다.
2. static 영역 : static 변수들을 보관한다.
3. 런타임 상수 풀: 프로그램을 실행하는데 필요한 공통 리터럴 상수를 보관한다. 예를 들어서 프로그램에 "hello"라는 리터럴 문자가 있으면 이런 문자를 공통으로 묶어서 관리한다. 이 외에도 프로그램을 효율 적으로 관리하기 위한 상수들을 관리한다.
2) 스택 영역(Stack Area)
- 자바 실행 시, 하나의 실행 스택이 생성된다. 각 스택 프레임은 지역 변수, 중간 연산 결과, 메서드 호출 정보 등을 포함한다.
- 스택 프레임: 스택 영역에 쌓이는 네모 박스가 하나의 스택 프레임이다. 메서드를 호출할 때마다 하나의 스 택 프레임이 쌓이고, 메서드가 종료되면 해당 스택 프레임이 제거된다.
3) 힙 영역(Heap Area)
- 객체(인스턴스)와 배열이 생성되는 영역이다. 가비지 컬렉션(GC)이 이루어지는 주요 영 역이며, 더 이상 참조되지 않는 객체는 GC에 의해 제거된다.
static 변수
static 키워드는 주로 멤버 변수와 메서드에 사용된다.
public class Data { public String name; public static int count; public Data(String name) { this.name = name; count++; } }
- name : 인스턴스 변수
인스턴스 변수는 인스턴스를 만들 때 마다 새로 만들어진다.
- count : 클래스 변수, static 변수, 정적 변수
static이 붙은 멤버 변수는 메서드 영역에서 관리한다.
static 이 붙은 멤버 변수 count는 인스턴스 영역에 생성되지 않는다. 대신 메서드 영역에서 이 변수를 관리한다.
클래스 변수는 자바 프로그램을 시작할 때 딱 1개가 만들어진다.
cf. 정적변수?
힙 영역에 생성되는 인스턴스 변수는 동적으로 생성되고, 제거된다. 반면에 static 인 정적 변수는 거의 프로그램 실행 시점에 딱 만들어지고, 프로그램 종료 시점에 제거된다. 정적 변수는 이름 그대로 정적이다.
public class DataCountMain { public static void main(String[] args) { Data3 data1 = new Data("A"); System.out.println("A count=" + Data.count); Data3 data2 = new Data("B"); System.out.println("B count=" + Data.count); Data3 data3 = new Data("C"); System.out.println("C count=" + Data.count); } }
- static 변수를 사용한 덕분에 공용 변수를 사용할 수 있다.
변수와 생명주기
1) 지역 변수(매개변수 포함) : 지역 변수는 스택 영역에 있는 스택 프레임 안에 보관된다. 메서드가 종료되면 스택 프 레임도 제거되는데 이때 해당 스택 프레임에 포함된 지역 변수도 함께 제거된다. 따라서 지역 변수는 생존 주기가 짧다.
2) 인스턴스 변수 : 인스턴스에 있는 멤버 변수를 인스턴스 변수라 한다. 인스턴스 변수는 힙 영역을 사용한다. 힙 영 역은 GC(가비지 컬렉션)가 발생하기 전까지는 생존하기 때문에 보통 지역 변수보다 생존 주기가 길다.
3) 클래스 변수 : 클래스 변수는 메서드 영역의 static 영역에 보관되는 변수이다. 메서드 영역은 프로그램 전체에서 사용하는 공용 공간이다. 클래스 변수는 해당 클래스가 JVM에 로딩되는 순간 생성된다. 그리고 JVM이 종료될 때까지 생명주기가 이어진다. 따라서 가장 긴 생명주기를 가진다.
static 메서드
public class DecoUtil { public static String deco(String str) { String result = "*" + str + "*"; return result; } }
- 정적 메서드는 정적 변수처럼 인스턴스 생성 없이 클래스 명을 통해서 바로 호출할 수 있다.
- 덕분에 불필요한 객체 생성 없이 편리하게 메서드를 사용할 수 있다.
정적 메서드 주의점
public class DecoData { private int instanceValue; private static int staticValue; public static void staticCall() { //instanceValue++; //인스턴스 변수 접근, compile error //instanceMethod(); //인스턴스 메서드 접근, compile error staticValue++; //정적 변수 접근 staticMethod(); //정적 메서드 접근 } public void instanceCall() { instanceValue++; //인스턴스 변수 접근 instanceMethod(); //인스턴스 메서드 접근 staticValue++; //정적 변수 접근 staticMethod(); //정적 메서드 접근 } private void instanceMethod() { System.out.println("instanceValue=" + instanceValue); } private static void staticMethod() { System.out.println("staticValue=" + staticValue); } }
public class DecoDataMain { public static void main(String[] args) { System.out.println("1.정적 호출"); DecoData.staticCall(); System.out.println("2.인스턴스 호출1"); DecoData data1 = new DecoData(); data1.instanceCall(); System.out.println("3.인스턴스 호출2"); DecoData data2 = new DecoData(); data2.instanceCall(); } }
1) static 메서드는 static 만 사용할 수 있다. 클래스 내부의 기능을 사용할 때, 정적 메서드는 static 이 붙은 정적 메서드나 정적 변수만 사용할 수 있다. 클래스 내부의 기능을 사용할 때, 정적 메서드는 인스턴스 변수나, 인스턴스 메서드를 사용할 수 없다.
2) 모든 곳에서 static을 호출할 수 있다. 정적 메서드는 공용 기능이다. 따라서 접근 제어자만 허락한다면 클래스를 통해 모든 곳에서 static 을 호출할 수 있다.
cf. 정적 메서드가 인스턴스의 기능을 사용할 수 없는 이유?
정적 메서드는 클래스의 이름을 통해 바로 호출할 수 있다. 그래서 인스턴스처럼 참조값의 개념이 없다. 특정 인스턴스의 기능을 사용하려면 참조값을 알아야 하는데, 정적 메서드는 참조값 없이 호출한다. 따라서 정적 메서드 내부에서 인스턴스 변수나 인스턴스 메서드를 사용할 수 없다.
cf. main() 메서드는 정적 메서드
인스턴스 생성 없이 실행하는 가장 대표적인 메서드가 바로 main() 메서드이다. main() 메서드는 프로그램을 시작하는 시작점이 되는데, 생각해 보면 객체를 생성하지 않아도 main() 메서드가 작 동했다. 이것은 main() 메서드가 static 이기 때문이다.
실무 소스를 보면 static 키워드가 자주 사용되는 것을 알 수 있다. 내가 직접 작성한 코드에서는 사용할 일이 없었지만 개발된 공통부분을 보면 특히 자주 사용된 것을 알 수 있다.
/** * (60) ex서비스 */ public static final String EXAMPLE_CONSTANT = "60";
클래스변수의 경우 constant 패키지 내에서 공용으로 사용될 상수들이 static으로 작성되어 있다.
참고로 final로 변하지 않는 값, 상수를 생성했기 때문에 static을 사용하게 되면 중복과 메모리 비효율 문제를 해결할 수 있다. 또한 보통 이런 상수들은 애플리케이션 전반에서 사용되기 때문에 public을 자주 사용한다.
/** * * <pre> * 1. 개요 : 요청 VO 를 요청 메시지로 변환한다. * 2. 처리내용 : * </pre> * @method name : ExMethod * */ public static String ExMethod(ExVo exVo) { StringBuilder tcpMessage = new StringBuilder(); ... return tcpMessage.toString(); }
클래스메서드의 경우에는 tcp전문을 json으로 변환해 준다거나 Item 목록의 iterator를 반환한다거나 역시 공통으로 사용되는 메서드들이 static으로 작성되어 있다.
(참고) 김영한 실전자바 - 기본 (섹션7. 자바 메모리 구조와 static)
728x90'자바' 카테고리의 다른 글
[JAVA] Class 클래스 (1) 2024.11.14 [JAVA] Int & Integer 차이점 그리고 wrapper 클래스 (0) 2024.08.22 [JAVA] 불변 객체 (0) 2024.08.19 [JAVA] equals() - 동일성과 동등성 (0) 2024.08.19 [JAVA] Object 클래스 (0) 2024.08.19