멤버 변수 용어 정리
public class Data {
public String name; // 인스턴스 변수
public static int count; // 클래스 변수, 정적 변수, static 변수
public Data(String name) {
this.name = name;
count++;
}
}
위 코드에서 name과 count 모두 멤버 변수이다. 그러나 static 유무에 따라 인스턴스 변수, 클래스 변수로 구분된다. 인스턴스 변수의 경우 인스턴스를 만들 때마다 새로 만들어지지만, 클래스 변수의 경우 일반적으로 자바 프로그램을 시작할 때 딱 1개가 만들어진다. 클래스 변수는 인스턴스 변수와는 달리 여러 곳에서 공유하는 목적으로 주로 사용된다.
변수와 생명주기
지역 변수 (파라미터 포함)
ㄴ 스택 영역에 있는 스택 프레임 안에 보관
ㄴ 메서드 종료 시 스택 프레임도 제거되므로 해당 스택 프레임에 포함된 지역 변수도 함께 제거
인스턴스 변수
ㄴ 힙 영역 사용
ㄴ 힙 영역은 GC가 발생하기 전까지 생존
클래스 변수
ㄴ 메서드 영역의 static 영역에 보관
ㄴ 메서드 영역은 프로그램 전체에서 사용하는 공용 공간이므로 JVM에 로딩되는 순간 생성
ㄴ 따라서 JVM 종료될 때까지 생존
클래스 변수에 접근하는 두 가지 방법
1. 인스턴스를 통한 접근
2. 클래스를 통한 접근
Data data1 = new Data("EX");
System.out.println(data1.count); // 인스턴스를 통한 접근
System.out.println(Data.count); // 클래스를 통한 접근
접근할 수 있는 방법은 많지만 클래스 변수는 클래스를 통한 접근을 해주는 것이 무조건 낫다. 왜냐하면 클래스 변수를 인스턴스 변수로 오해할 수 있기 때문이다. 아래에 조금 더 이해하기 쉽게 예시를 들어보겠다.
Data data1 = new Data("A");
System.out.println(data1.count);
Data data2 = new Data("B");
System.out.println(data2.count);
Data data3 = new Data("C");
System.out.println(data3.count);
어떠한가? data1.count, data2.count, data3.count는 실제로 같은 메모리에 할당되어 있음에도, 각각 따로 할당되어 있는 듯 보인다. 이제 느낌 비교를 위해, 클래스를 통해 접근한 경우도 보자.
Data data1 = new Data("A");
System.out.println(Data.count);
Data data2 = new Data("B");
System.out.println(Data.count);
Data data3 = new Data("C");
System.out.println(Data.count);
클래스를 통해 접근하니, count는 누가 봐도 static 변수임을 쉽게 알 수 있다. (내가 짠 코드지만 나만 쓰는 것이 아닐 수 있기 때문에 항상 가독성을 고려해야 한다!)
멤버 메서드 용어 정리
// 인스턴스 메서드
public class DecoStr1 {
public String deco(String str) {
return "* " + str + " *";
}
}
// 정적 메서드 (또는 static 메서드)
public class DecoStr2 {
public static String deco(String str) {
return "* " + str + " *";
}
}
멤버 메서드가 어떠한 인스턴스 변수조차 포함하지 않는 경우, 객체를 굳이 생성해야 하나 싶은 생각이 든다. 그럴 때 정적 메서드를 사용하면 객체 생성 없이 DecoStr2.deco("funczun") 이런 식으로 사용할 수 있어 편리하다.
정적 메서드의 한계점
public class Deco {
private int instanceValue;
private static int staticValue;
public static void staticCall() {
instanceValue++; // 인스턴스 변수 접근 (불가능: Compile Error)
instanceMethod(); // 인스턴스 메서드 접근 (불가능: Compile Error)
staticValue++; // 정적 변수 접근 (가능)
staticMethod(); // 정적 메서드 접근 (가능)
}
private void instanceMethod() {
System.out.println("instanceValue: " + instanceValue);
}
private static void staticMethod() {
System.out.println("staticValue: " + staticValue);
}
}
static 메서드가 만능은 아니다. static 메서드는 클래스 자체에 속해, 인스턴스 생성 없이 호출할 수 있는 메서드인데, 인스턴스 변수는 인스턴스를 생성해야 생긴다. 인스턴스를 생성하지 않았는데 무슨 인스턴스 변수에 접근할 수 있겠는가? (즉, static 메서드는 this를 알 수 없다.) 당연히 인스턴스 메서드 또한 접근할 수 없다.
'프로그래밍 > 배웠어, 자바' 카테고리의 다른 글
[Java] super 키워드 / 상속과 메모리 구조 (2) | 2025.01.23 |
---|---|
[Java] static final / 매직 넘버와 상수 (3) | 2025.01.21 |
[IntelliJ] 인텔리제이 단축키 모음 (0) | 2025.01.10 |
[Java] '예외 처리' 완전 정복하기 (0) | 2025.01.07 |
[Java] Scanner, BufferedReader (0) | 2025.01.06 |