09009
[Java] 클래스변수, 인스턴스변수, 초기화 블럭 본문
인스턴스변수
• 클래스의 인스턴스를 생성할 때 만들어진다
• 각 인스턴스는 독립적인 저장공간을 소유하고 서로 다른 값을 가질 수 있다
• 인스턴스마다 고유한 상태를 유지해야 하는 경우, 인스턴스 변수로 선언한다
클래스변수
• 선언 방법: 인스턴스변수 앞에 static 작성
• 클래스변수는 모든 인스턴스가 공통된 저장공간을 공유함
• 한 클래스의 모든 인스턴스들이 공통적인 값을 유지해야 하는 경우, 클래스변수로 선언한다.
• 인스턴스 변수와 달리 인스턴스를 생성하지 않고 바로 사용 가능 ('클래스이름.클래스변수'와 같은 형식으로 사용)
• 클래스가 메모리에 로딩될때 생성, 프로그램이 종료될 때까지 유지
static
• static은 메서드 영역에 생성된다.
• 프로그램이 시작되는 시점에 생성된다. (딱 1개)
• static은 소멸이 되지 않는다.
• static은 접근할 때 인스턴스를 생성하지 않고도 바로 접근이 가능하다. (클래스명.기본변수명)
• static은 어디서든 호출이 가능하다.
• static은 this를 사용할 수 없다.
class Card {
String kind; // 인스턴스변수
int number; // 인스턴스변수
static int width = 100; // 클래스변수
static int height = 250; // 클래스변수
}
인스턴스변수 : 인스턴스가 생성될 때마다 생성되므로 인스턴스마다 각기 다른 값 유지 가능
클래스변수: 모든 인스턴스가 하나의 저장공간을 공유하여 항상 공통된 값을 가짐
!! 인스턴스마다 개별적인 값을 가져야하는 변수는 인스턴스변수로 선언하고,
모든 인스턴스가 공통적인 값을 가져야하는 변수는 클래스 변수로 선언해야한다. !!
클래스변수의 초기화 시점: 클래스가 처음 로딩될 때 단 한 번 초기화 수행
인스턴스변수의 초기화 시점: 인스턴스가 생성될 때마다 각 인스턴스별로 초기화 수행
✍ 입력
class Static2 {
int x;
static int y;
void add() {
x++;
y++;
}
}
public class Static2Ex {
public static void main(String[] args) {
for(int i = 0; i < 10; i++) {
Static2 st = new Static2();
st.add();
System.out.println("x = " + st.x + ", y = " + st.y);
}
}
}
위의 소스코드에서 Static2 클래스에 선언된 x는 인스턴스변수이고, y는 클래스변수이다.
💻 출력
x = 1, y = 1
x = 1, y = 2
x = 1, y = 3
x = 1, y = 4
x = 1, y = 5
x = 1, y = 6
x = 1, y = 7
x = 1, y = 8
x = 1, y = 9
x = 1, y = 10
인스턴스변수 x는 인스턴스가 생성될때마다(위의 소스코드의 경우, main메서드 안에서 반복문 수행 중 계속 인스턴스 생성) 0으로 초기화(자료형이 int이므로)되므로 add()메서드를 수행할 때마다 항상 1이 나오는 것을 확인할 수 있다.
하지만 클래스변수 y는 클래스가 처음 로딩될 때 단 한번만 0으로 초기화되므로 main메서드 안에서 반복문 수행 중 계속 인스턴스를 생성하더라도 초기화되지 않기 때문에 값이 계속 누적된다는 사실을 확인할 수 있다.
초기화 블럭
class Hello {
static { /* 클래스 초기화블럭 */ }
{ /* 인스턴스 초기화블럭 */ }
}
클래스 초기화블럭: 클래스가 메모리에 처음 로딩될 때 단 한번만 수행
인스턴스 초기화블럭: 인스턴스가 생성될 때마다 수행
✍ 입력
public class HaaLand {
static { // 클래스 초기화 블럭
System.out.println("초기화 블럭입니다");
}
{ // 인스턴스 초기화 블럭
System.out.println("인스턴스 블럭입니다");
}
public HaaLand() {
System.out.println("생성자입니다");
}
public static void main(String[] args) {
System.out.println("첫번째 블럭 테스트중입니다");
HaaLand h1 = new HaaLand();
System.out.println("두번째 블럭 테스트중입니다");
HaaLand h2 = new HaaLand();
}
}
💻 출력
초기화 블럭입니다
첫번째 블럭 테스트중입니다
인스턴스 블럭입니다
생성자입니다
두번째 블럭 테스트중입니다
인스턴스 블럭입니다
생성자입니다
코드가 실행되면서 클래스 HaaLand가 메모리에 로딩이 될 때, 클래스 초기화 블럭이 가장 먼저 수행되어 "초기화 블럭입니다"가 제일 먼저 출력된다. 그 후, main메서드가 수행되어 HaaLand 인스턴스가 생성되면서 인스턴스 초기화 블럭이 먼저 수행되고 다음으로 생성자가 출력된다.
위의 소스코드 출력 결과에서도 알 수 있듯이, 클래스 초기화 블럭은 처음 메모리에 로딩될 때 한번만 수행되고 인스턴스 초기화 블럭은 인스턴스가 생성될 때마다 수행된다는 사실을 확인할 수 있다.
✍ 입력
class Product {
static int count;
int serialNo;
{ // 인스턴스 초기화 블럭
++count;
serialNo = count;
}
}
public class ProductTest {
public static void main(String[] args) {
Product p1 = new Product();
Product p2 = new Product();
Product p3 = new Product();
System.out.println("p1의 제품번호(serialNo)는 " + p1.serialNo);
System.out.println("p2의 제품번호(serialNo)는 " + p2.serialNo);
System.out.println("p3의 제품번호(serialNo)는 " + p3.serialNo);
System.out.println("생산된 제품의 수는 모두 " + Product.count + "개입니다."); // count는 클래스변수이므로 클래스이름.클래스변수
}
}
Product 클래스의 인스턴스를 생성할 때마다 인스턴스 초기화 블럭이 수행된다.
인스턴스 초기화 블럭이 수행되어 클래스변수인 count의 값을 1 증가시키고 그 값을 인스턴스변수 serialNo에 저장하는 방식으로 작동된다.
💻 출력
p1의 제품번호(serialNo)는 1
p2의 제품번호(serialNo)는 2
p3의 제품번호(serialNo)는 3
생산된 제품의 수는 모두 3개입니다.
count를 인스턴스 변수로 선언했다면 결과는 어떻게 출력될까?
✍ 입력
class Product {
int count;
int serialNo;
{ // 인스턴스 초기화 블럭
++count;
serialNo = count;
}
}
public class ProductTest {
public static void main(String[] args) {
Product p1 = new Product();
Product p2 = new Product();
Product p3 = new Product();
System.out.println("p1의 제품번호(serialNo)는 " + p1.serialNo);
System.out.println("p2의 제품번호(serialNo)는 " + p2.serialNo);
System.out.println("p3의 제품번호(serialNo)는 " + p3.serialNo);
}
}
💻 출력
p1의 제품번호(serialNo)는 1
p2의 제품번호(serialNo)는 1
p3의 제품번호(serialNo)는 1
count를 인스턴스 변수로 선언할 경우, 인스턴스가 생성될 때마다 0으로 초기화되기 때문에 모든 Product 인스턴스의
제품번호는 항상 1이 출력된다.
! 중요 !
멤버변수는 자동으로 초기화되므로 초기화하지 않고도 값을 참조할 수 있다.
지역변수는 사용하기 전에 반드시 초기화하여야 한다.
같은 클래스 내의 메서드는 서로 객체의 생성이나 참조변수 없이 직접 호출이 가능하다.
static 변수의 초기화에 인스턴수변수를 사용할 수 없다. 사용하려면, 객체를 생성한 후 인스턴스변수를 사용해야 한다.
static 메서드에서는 인스턴스변수, 인스턴스메서드를 사용할 수 없다.
인스턴스 메서드에서는 클래스변수나 클래스메서드를 사용하는 것은 가능하다.
/
5/7
'Back-End > JAVA' 카테고리의 다른 글
[Java] JDBC (1) (eclipse와 Oracle, MySQL) (0) | 2023.03.23 |
---|---|
[Java] 접근 제어자 (0) | 2023.03.19 |
[Java] (중요) 참조형 반환타입의 메서드 (0) | 2023.03.18 |
[Java] 쓰레드 (0) | 2023.03.13 |
[Java] Generic (0) | 2023.03.12 |