static 변수
static
static
키워드는 주로 멤버 변수와 메서드에 사용된다.
static의 필요성
- static 변수는 쉽게 이야기해서 클래스인 붕어빵 틀이 특별히 관리하는 변수이다.
- 붕어빵 틀은 1개이므로 클래스 변수도 하나만 존재한다.
- 반면, 인스턴스 변수는 붕어빵인 인스턴스의 수 만큼 존재한다.
static 변수
public class Data {
public String name;
public static int count; //static
}
- 멤버변수는 static이 붙은 것 / 아닌 것으로 분류한다.
인스턴스 변수
- static이 붙지 않은 멤버 변수
- ex. name
- 인스턴스를 생성해야만 사용 가능
- 인스턴스에 소속됨
- 인스턴스를 만들 때마다 생성됨
- static이 붙지 않은 멤버 변수
클래스 변수
(정적 변수, static 변수)- static이 붙은 멤버 변수
- ex. count
- 인스턴스와 무관하게 클래스에 바로 접근하여 사용 가능
- 클래스 자체에 소속되어 있음
- 자바 프로그램을 시작할 때 오직 1개만 만들어짐.
- 인스턴스와 달리 보통 여러곳에서 공유하는 목적으로 사용됨
- static이 붙은 멤버 변수
변수와 생명주기
지역변수
- 스택 영역의 스택 프레임 내부에 보관됨
- 메서드가 종료되면 스택 프레임도 종료됨. 이때, 해당 스택 프레임에 포함된 지역 변수도 함께 제거됨
-> 지역변수는 생존 주기가 짧음!
인스턴스 변수
- 인스턴스에 있는 멤버 변수
- 힙 영역을 사용함
- 힙 영역은 가비지 컬렉션이 발생하기 전까지는 생존함.
-> 일반적으로 지역변수보다 생존 주기가 길다.
클래스 변수
- 메서드 영역의 static 영역에 보관되는 변수
- 메서드 영역은 프로그램 전체에서 사용하는 공용공간임.
- 클래스가 JVM에 로딩되는 순간 생성됨
❓ 클래스가 JVM에 로딩된다는 것은 무슨 의미일까?
- 해당 클래스가 사용될 준비가 되었다는 것을 의미함.
- 이 과정에서 클래스의 데이터가 메서드 영역에 배치됨.
- But, 프로그램을 시작할 때 모든 클래스와 클래스 변수가 JVM에 한번에 로딩되지는 않음.
- 클래스는 필요할 때 동적으로 로딩됨.
❓ 클래스가 JVM에 로딩되는 시점은 언제일까?
- 해당 클래스의 인스턴스가 처음으로 생성될 때
- 해당 클래스의 static 멤버(변수나 메서드)에 접근할 때
- Class.forName() 메서드를 통해 명시적으로 해당 클래스를 로딩될때
✏️ 클래스가 로딩되는 순간, 클래스 변수도 초기화됨.
-> 메서드 영역의 static 영역에 할당됨. 그리고, JVM이 종료될 때까지 그 생명주기가 유지됨.
=> 클래스 변수는 해당 클래스의 모든 인스턴스에 의해 공유되며, 클래스가 로드된 후부터 JVM이 종료될 때까지 계속 존재하게 된다.
- JVM이 종료될 때까지 생존주기가 이어짐
-> 생존 주기가 가장 김!
생명 주기 : 지역 변수 < 인스턴스 변수 < 클래스 변수
💡 static이 정적인 이유
- 힙 영역에 생성되는 인스턴스 변수는 동적으로 생성&제거됨.
- 반면, 정적 변수인
static
은 프로그램 실행 시점에 만들어지고, 프로그램 종료 시점에 제거됨.
정적 변수 접근 방법
- static 변수는 클래스를 통해 바로 접근할 수도 있고, 인스턴스를 통한 접근도 가능하다
package static1;
public class DataCountMain {
public static void main(String[] args) {
Data data1 = new Data("A");
Data data2 = new Data("B");
//인스턴스를 통한 접근
System.out.println("A count=" + data2.count); //2
//클래스를 통합 접근
System.out.println(Data.count); //2
}
}
//둘의 차이는 없다. 둘다 결과적으로 정적 변수에 접근한다.
data2.count
: 인스턴스를 통한 접근-
- 정적 변수의 경우, 인스턴스를 통한 접근은 비추!
- 코드를 읽을 때 마치 인스턴스 변수에 접근하는 것처럼 보일 수 있기 때문
- 정적 변수의 경우, 인스턴스를 통한 접근은 비추!
Data.count
: 클래스를 통한 접근- 정적 변수에 접근할 때는 클래스를 통해서 접근하자. (클래스에서 공용으로 관리하기 때문에 클래스를 통한 접근이 더 명확함)
static 메서드
static 메서드의 필요성
인스턴스 메서드 활용
package static2;
public class DecoUtil {
public String deco(String str) {
String result = "*" + str + "*";
return result;
}
}
package static2;
public class DecoMain {
public static void main(String[] args) {
String s = "hello java";
DecoUtil utils = new DecoUtil(); //객체생성
String deco = utils.deco(s); //객체를 통해 메서드 호출
System.out.println("before: " + s);
System.out.println("after: " + deco);
}
}
before: hello java
after: *hello java*
deco()
메서드를 호출하려면DecoUtil
의 인스턴스를 먼저 생성해햐 함.deco()
기능은 단순히 기능만 제공할 뿐임. => 메서드 하나만의 사용을 위해 인스턴스를 생성하는 것은 불편하다.
static 메서드 활용
package static2;
public class DecoUtil {
public static String deco(String str) {
String result = "*" + str + "*";
return result;
}
}
package static2;
public class DecoMain {
public static void main(String[] args) {
String s = "hello java";
String deco = DecoUtil.deco(s); //클래스를 통한 메서드 호출
System.out.println("before: " + s);
System.out.println("after: " + deco);
}
}
package static2;
public class DecoMain {
public static void main(String[] args) {
String s = "hello java";
String deco = DecoUtil.deco(s); //클래스를 통한 메서드 호출
System.out.println("before: " + s);
System.out.println("after: " + deco);
}
}
before: hello java
after: *hello* java
static
이 붙은 정적 메서드는 객체 생성 없이클래스명 + .(dot) + 메서드명
으로 바로 호출 가능- ❓ 인스턴스 메서드가 객체를 통한 접근만 가능한 이유*
인스턴스 메서드, static 메서드 모두 메서드 영역에 저장된다.
그런데, static 메서드 클래스를 통한 접근이 가능하고, 인스턴스 메서드는 클래스를 통한 접근이 불가능하다. - 인스턴스 메서드는 객체가 생성되어야만 해당 메서드에 접근할 수 있도록 설계되어있기 때문!(저장구조의 차이가 아니다.)
- ex) String 객체가 생성되어야만 length메서드 사용 가능
String example = "Hello, World!"; int length = example.length();
- ex) String 객체가 생성되어야만 length메서드 사용 가능
static 메서드 사용 방법
- 정적 메서드는 객체의 생성 없이도 클래스에 있는 메서드를 바로 호출할 수 있다.
- But, 정적 메서드는 언제나 사용할 수 있는 것이 아님!
- static 메서드는 static만 사용가능하다.
- 클래스 내부 기능을 사용할 때,
- 정적 메서드는
static이 붙은 정적 메서드
or정적 변수
만 사용 가능 - 정적 메서드는
인스턴스 변수
or인스턴스 메서드
사용 불가능
- 정적 메서드는
- 클래스 내부 기능을 사용할 때,
- static의 호출은 모든 곳에서 가능하다.
- 정적 메서드는 공용기능!
- 접근 제어자만 허락한다면 클래스를 통해 어디에서나 static 호출이 가능.
static 메서드 용어
클래스 메서드
: static이 붙은 멤버 메서드- 인스턴스와 무관하게 클래스에 바로 접근하여 사용 가능
- 클래스 자체에 소속됨
인스턴스 메서드
: static이 붙지 않은 멤버 메서드- 인스턴스를 생성해야 사용 가능
- 인스턴스에 소속됨
static 메서드 접근법
- 인스턴스를 통한 접근 :
data3.staticCall()
- 정적 메서드의 경우, 인스턴스를 통한 접근은 비추!
- 코드를 읽을 때 마치 인스턴스 메서드에 접근하는 것 처럼 오해할 수 있기 때문
- 정적 메서드의 경우, 인스턴스를 통한 접근은 비추!
- 클래스를 통한 접근 :
DecoData.staticCall()
- 정적 메서드에 접근할 때는 클래스를 통해서 접근하자. (정적메서드는 클래스에서 공용으로 관리되기 때문에 클래스를 통한 접근이 더 명확!)
'Java > 문법' 카테고리의 다른 글
[JAVA 중급 스터디 - 7~9회차] 상속 (0) | 2024.03.20 |
---|---|
[JAVA 중급 스터디 - 6회차] final (0) | 2024.03.20 |
[JAVA 중급 스터디 - 3회차] 자바의 메모리 구조 (0) | 2024.03.09 |
[JAVA 중급 스터디 - 2회차] 접근 제한자와 캡슐화 (0) | 2024.03.08 |
[JAVA 중급 스터디 - 1회차] 기본형/참조형, Wrapper Class생성자, 패키지 (0) | 2024.03.08 |